BackBone Test

by evan

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<div id="outline">
    <ul></ul>
</div>
<div id="templates">
    <ul>
        <li class="planElement">
             <h4 class="title"></h4>
            <ul class="section-list">
                <li>xxx</li>
            </ul>
        </li>
    </ul>
</div>

CSS

#templates {
    display: none;
}
.section-list {
    display: none;
}

JavaScript

var PlanElement, PlanElementCollection, PlanElementView, OutlineView, planElements, outlineView;

var PlanElement = Backbone.Model.extend({
    idAttribute: 'uuid',
    defaults: {
        title: 'New PlanElement'
    },
    validate: function (attrs) {
        if (typeof attrs.uuid === 'undefined') {
            return "No UUID!";
        }
    },
    toggleExpanded: function () {
        this.set('expanded', !this.get('expanded'));
    }
});

PlanElementCollection = Backbone.Collection.extend({
    model: PlanElement
});

PlanElementView = Backbone.View.extend({

    initialize: function () {        
        // set element to a clone of the planElement template
        this.setElement($('#templates .planElement').clone());
        this.listenTo(this.model, 'change', this.render);
        this.listenTo(this.model, 'remove', this.remove);
    },

    events: {
        'click h4': 'clickTitle'
    },

    render: function () {
        this.$('.title').text(this.model.get('title'));
        if (this.model.get('expanded')) {
            this.$('.section-list').show();
        } else {
            this.$('.section-list').hide();
        }

        return this;
    },

    remove: function () {
        this.$el.remove();
        this.stopListening();
    },

    clickTitle: function () {
        this.model.toggleExpanded();
    }
});

OutlineView = Backbone.View.extend({
    el: "#outline",
    initialize: function () {
        this.planElementList = this.$('ul');

        this.listenTo(planElements, 'add', this.addOne);
        this.listenTo(planElements, 'reset', this.addAll);
    },

    addOne: function (planElementModel) {
        var planElement = new PlanElementView({
            model: planElementModel
        });
        this.planElementList.append(planElement.render().el);
    },

    addAll: function () {
        this.planElementList.html('');
        planElements.each(this.addOne, this);
    }

});

planElements = new PlanElementCollection();
outlineView =...