Pointers
Syncs a model or collection with an element. Supports two-way syncs. Respects garbage collection and bottom-up rendering. Reactive.
by Benjamin Lupton
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.0/backbone-min.js"></script>
<script src="//wzrd.in/bundle/[email protected]"></script>
<header>
<h1><a href="https://github.com/bevry/pointers" target="_blank">Pointers</a></h1>
<p>Syncs a model or collection with an element. Supports two-way syncs. Respects garbage collection and bottom-up rendering. Reactive.</p>
</header><hr/>
<div class="app">
<ul class="people">
<li class="person">
<span class="name"></span>
<button class="edit">Edit</button>
</li>
</ul>
<div class="person-edit-container">
<div class="person-edit">
<input type="text" class="name"></input>
<button class="delete">Delete</button>
</div>
</div>
<div class="person-add-container">
<div class="person-add">
<input type="text" class="name"></input>
<button class="add">Add</button>
</div>
</div>
</div>
JavaScript
var Backbone = window.Backbone;
var Pointer = require('pointers').Pointer;
var PersonModel = Backbone.Model;
var PersonCollection = Backbone.Collection.extend({
model: PersonModel
});
var PointerView = Backbone.View.extend({
pointers: null, // becomes an array
point: function(opts){
var pointer = new Pointer(opts);
this.pointers = this.pointers || [];
this.pointers.push(pointer)
return pointer;
},
destroy: function(){
this.pointers.forEach(function(pointer){
pointer.destroy();
});
this.pointers = null;
return this.remove();
}
});
var PersonView = PointerView.extend({
el: $('.person').remove().first().prop('outerHTML'),
events: {
'click .edit': 'onEdit'
},
onEdit: function(){
this.$el.trigger('editPerson', this.model);
return this;
},
render: function(){
this.point({
item: this.model,
itemAttributes: ['name'],
element: this.$el.find('.name')
}).bind();
return this;
}
});
var PersonEditView = PointerView.extend({
el: $('.person-edit').remove().first().prop('outerHTML'),
events: {
'click .delete': 'onDelete'
},
onDelete: function(){
this.model.destroy();
this.destroy();
return this;
},
render: function(){
this.point({
item: this.model,
itemAttributes: ['name'],
element: this.$el.find('.name'),
itemSetter: true
}).bind();
return this;
}
});
var PersonAddView = PointerView.extend({
el: $('.person-add').remove().first().prop('outerHTML'),
events: {
'click .add': 'onAdd'
},
onAdd: function(){
this.$el.trigger('addPerson', this.model);
return this;
},
render: function(){
this.point({
item: this.model,
itemAttributes: ['name'],
...