//extend Backbone.Model and setup a Contact model class/constrcutor var Contact = Backbone.Model.extend({ defaults: { firstName: null, lastName: null, phone: null }, getName: function () { return this.get('firstName') + ' ' + this.get('lastName'); } }); /*create a contacts collection, tell it which model is used for the collection, seed it with one contact model*/ var contacts = new Backbone.Collection({ //seed it with some data firstName: 'Jane', lastName: 'Doe', phone: '111-111-1111' }, { model: Contact }); //create a AddContactsView class, then create instance var AddContactsView = Backbone.View.extend({ el: 'fieldset', events: { 'click button': 'addContact' }, addContact: function () { var firstName = this.$('#firstName').val(); var lastName = this.$('#lastName').val(); var phone = this.$('#phone').val(); if (firstName && lastName && phone) { contacts.add({ //this will invoke the Backbone internal 'add' event firstName: firstName, lastName: lastName, phone: phone }); this.$('input').val(''); } } }); var addContactsViewInstance = new AddContactsView(); //create ContactListView class, then create instance var ContactListView = Backbone.View.extend({ el: '#contacts', events: { 'click li button': 'removeContact' }, initialize: function () { this.render(); //render list this.listenTo(contacts, 'add remove', this.render); //the magic }, removeContact: function (e) { $(e.target).parent('li').remove(); contacts.findWhere({ firstName: $(e.target).parent('li').find('span').text().split(' ')[0].trim(), lastName: $(e.target).parent('li').find('span').text().split(' ')[1].trim() }).destroy(); //this will invoke the internal 'remove' event }, render: function () { if (contacts.length > 0) { this.$el.empty(); contacts.each(function (contact) { this.$el.append('<li><span>' + contact.getName() + '</span>'+' / '+ contact.get('phone') + '<button type="button" class="btn-xs btn-danger removeContactBtn">X</button></li>'); }, this); } } }); var contactListViewInstance = new ContactListView();
body { margin:10px; } .removeContactBtn{ margin-left:10px; } #contacts { margin-bottom:0px; } #contacts li{ margin-bottom:10px; margin-left:10px; display: inline-block; } #contacts li:last-child{ margin-bottom:0px; } .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; }
<small>read: <a href="http://tech.pro/tutorial/1476/part-2-backbonejs-deconstructed">Part 2: Backbone.js Deconstructed</a></small> <h4>Contact List:</h4> <div class="panel panel-default"> <div class="panel-body"> <ul id="contacts" class="list-unstyled"></ul> </div> </div> <h4>Add Contact:</h4> <fieldset class="form-inline" role="form"> <div class="form-group"> <input type="text" class="form-control" id="firstName" value="John" placeholder="First Name" style="width:120px;" /> </div> <div class="form-group"> <input type="text" class="form-control" id="lastName" value="Doe" placeholder="Last Name" style="width:120px;" /> </div> <div class="form-group"> <input type="tel" class="form-control" id="phone" value="000-000-0000" placeholder="Phone #" style="width:120px;" /> </div> <br> <br> <button class="btn btn-primary btn-sm">Add</button> </fieldset> <hr /> <small>Disclaimer: This code is for learning about a model, collection, and view. Parts of it are pretty ugly and not optimized. Don't worry about it, just worry about grokking the Backbone.js parts which are contrived to create a stepping stone and thus written to this end.</small> </div>