AngularJS - Nested Directives++

Thanks Ali Mills for the inspiration! http://jsfiddle.net/alimills/rCbMv And Thomas Burleson for some great feedback on the code.

by andytjoslin

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="http://code.angularjs.org/1.0.0rc12/angular-1.0.0rc12.js"></script>
<div ng-app="myApp">
    <script type="text/ng-template"  id="partials/notebook-directive.html">
    <ul id="notes" class="thumbnails">
        <li ng-repeat="note in ngModel">
            <my-note class="span2 thumbnail">
                <button class="btn btn-large close pull-right" ng-click="$parent.deleteNote(note.id)">&times;</button>
                <hr/>
                <p>{{note.title}}</p>
            </my-note>
        </li>
    </ul>
    </script>

    <div id="app" ng-controller="NotebookCtrl">
        <div class="page-header">
            <h1>AngularJS Sticky Notes</h1>
        </div>
        <div class="form-actions">
            <div class="input-append">
                <input class="span3" ng-model="noteTitle" size="16" type="text" placeholder="Add a note">
                <button class="btn btn-success" type="button"
                        ng-cloak ng-show="noteTitle" ng-click="addNote(noteTitle)">Add Note
                </button>
            </div>
        </div>
        <my-notebook ng-model="myNotebook"></my-notebook>
    </div>
</div>

CSS

.ui-state-highlight { background-color: #EEEEEE; }

JavaScript

angular.module('myApp', [])
    .directive('myNotebook', function ($log) {
        return {
            restrict:"E",
            templateUrl:"partials/notebook-directive.html",
            link: function(scope, elm, attrs) {
                var notebook = {};
                var nextNoteId = 0;
                
                notebook.notes = [];
                
                notebook.addNote = function(noteTitle) {
                    notebook.notes.push({
                        title: noteTitle,
                        id: nextNoteId++
                    });   
                };
                
                notebook.deleteNote = function(id) { 
                    var newNotes=[];
                    angular.forEach(notebook.notes, function(note) {
                        if (note.id !== id)
                            newNotes.push(note);
                    });
                    notebook.notes = newNotes; 
                }
                
                scope[attrs.ngModel] = notebook;
            }
        };
    })
    .directive('myNote', function () {
        return {
            restrict:'E',
            link:function (scope, element, attrs) {
                var $el = $(element);

                $el.hide().fadeIn('slow');

                $('#notes').sortable({
                    placeholder:"ui-state-highlight", forcePlaceholderSize:true
                });
            }
        };
    });


function NotebookCtrl($scope) {
    angular.forEach(['Note 1','Note 2','Note 3'], function(note) {
        //$scope.myNotebook.addNote(note.title);
    });
}