昨天我们一起学习了Backbone,最后做了一个备忘录的例子,说是做了不如说是看了下官方提供的例子,所以最终我感觉我们还是没能掌握Backbone,今天还得做个其它例子先。
然后前面也只是草草学习了RequireJS,没做demo,这个周末又在看电影打游戏睡觉瞎折腾,转眼就周日下午了,突然诗性大起,于是作诗一首先:
古有通宵看A片,今有彻夜码代码
好吧,我们开始今天的学习吧,我们今天先用backbone做一个通讯录的东西,然后使用requireJS组装之。
部分参考:the5fire的技术博客
简单例子
做之前我们先来个简单的例子:
1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <title></title> 4 </head> 5 <body> 6 <div id="contactapp"> 7 <header> 8 <h1> 9 通讯录</h1> 10 </header> 11 <section id="main"> 12 <ul id="contact-list"> 13 </ul> 14 </section> 15 <div class="create"> 16 <input type="button" value="增加(弹出框)" id="addDia" /> 17 </div> 18 </div> 19 </body> 20 <script src="js/jquery.js" type="text/javascript"></script> 21 <script src="js/underscore.js" type="text/javascript"></script> 22 <script src="js/backbone.js" type="text/javascript"></script> 23 <script type="text/javascript"> 24 (function ($) { 25 var Contact = Backbone.Model.extend({ 26 //创建一个contact对象,拥有name属性 27 name: null 28 }); 29 var ContackList = Backbone.Collection.extend({ 30 initialize: function (models, options) { 31 //contact集合 32 this.bind('add', options.view.addOne); 33 } 34 }); 35 var AppView = Backbone.View.extend({ 36 el: $('body'), 37 initialize: function () { 38 //实例化集合,并传入AppView对象 39 this.contacts = new ContackList(null, { view: this }); 40 }, 41 events: { 42 'click #addDia': 'addDia' 43 }, 44 addDia: function () { 45 var name = prompt('请输入姓名'); 46 var c = new Contact({ name: name }); 47 this.contacts.add(c); 48 }, 49 addOne: function (model) { 50 $('#contact-list').append('<li>' + model.get('name') + '</li>'); 51 } 52 }); 53 var app = new AppView(); 54 })(jQuery); 55 </script> 56 </html>
PS:感谢the5fire给出的例子,我和我的小伙伴一下都明白了。。。。
以上代码涉及到Backbone三个部分:View、Model、Collection,我们在addOne里面使用了jquery绑定dom以后会将之消除。
各位请看这个代码:
this.bind('add', options.view.addOne);
在集合中绑定了add事件,在addDia最后执行了,然后触发集合的事件,才最后将dom添加完成。
知识回顾(参考the5fire)
the5fire关于backbone的文章写的很好(http://www.the5fire.com),我们一起来看看顺便回顾下我们的知识。
model
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } }); var man = new Man;
这个是一个model最简单的model,initialize中的方法一来就会执行,这里就会弹出框:
对象赋值
Man = Backbone.Model.extend({ initialize: function () { alert('Hey, you create me!'); }, defaults: { name: '张三', age: '38' } }); var man = new Man; alert(man.get('name')); //man.set({ name: 'the5fire', age: '10' });
若是不赋值就使用默认值,若是赋值则采用给的值。
事件与方法
Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); }, defaults: { name:'张三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } }); var man = new Man; man.set({name:'the5fire'}) //触发绑定的change事件,alert。
可以定义方法aboutMe,也可以在initialize中绑定事件以监听某个属性的变化。
验证及错误提示
Man = Backbone.Model.extend({ initialize: function () { this.bind("error", function (model, error) { alert(error); }); }, validate: function (attributes) { if (attributes.name == '') { return "name不能为空!"; } }, }); var man = new Man; man.set({ name: '' }); //根据验证规则,弹出错误提示。
此处验证不通过便会触发错误提示。
PS:经测试并没有提示,问题后面跟进
PS:最后证明有反应,我调试页面用错了
对象持久化
对象持久化可以是服务器也可以是本地存储,具体就不展开了。
collection
集合其实就是model的有序集合,经过周末的学习,我们应该比较熟悉了:
Book = Backbone.Model.extend({ defaults: { // 感谢网友蓝色动力指正改为defaults title: 'default' }, initialize: function () { //alert('Hey, you create me!'); } }); BookShelf = Backbone.Collection.extend({ model: Book }); var book1 = new Book({ title: 'book1' }); var book2 = new Book({ title: 'book2' }); var book3 = new Book({ title: 'book3' }); //var bookShelf = new BookShelf([book1, book2, book3]); //注意这里面是数组,或者使用add var bookShelf = new BookShelf; bookShelf.add(book1); bookShelf.add(book2); bookShelf.add(book3); bookShelf.remove(book3); //基于underscore这个js库,还可以使用each的方法获取collection中的数据 bookShelf.each(function (book) { alert(book.get('title')); });
fetch
我们若是要与服务器通讯获取数据,需要先为bookshelf定义url:
bookShelf.fetch({ url: '/getbooks/', success: function (collection, response) {
collection.each(function (book) {
alert(book.get('title'));
});
}, error: function () {
alert('error');
}
});
//对应的BookShelf的返回格式如下: [{'title':'book1'},{'title':'book2'}.....]
此后我们需要将页面的dom与数据同步,所以会用到reset事件;
bookShelf.bind('reset',showAllBooks);
showAllBooks = function(){
bookShelf.each(function(book){
//将book数据渲染到页面。
});
}
1 <html> 2 <head> 3 <title>the5fire-backbone-collection</title> 4 </head> 5 <body> 6 </body> 7 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script> 8 <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script> 9 <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script> 10 <script> 11 (function ($) { 12 //collection是一个简单的models的有序集合 13 //1、一个简单的例子 14 15 Book = Backbone.Model.extend({ 16 defaults : { // 感谢网友蓝色动力指正改为defaults 17 title:'default' 18 }, 19 initialize: function(){ 20 //alert('Hey, you create me!'); 21 } 22 }); 23 BookShelf = Backbone.Collection.extend({ 24 model : Book 25 }); 26 27 var book1 = new Book({title : 'book1'}); 28 var book2 = new Book({title : 'book2'}); 29 var book3 = new Book({title : 'book3'}); 30 31 //var bookShelf = new BookShelf([book1, book2, book3]); //注意这里面是数组,或者使用add 32 var bookShelf = new BookShelf; 33 bookShelf.add(book1); 34 bookShelf.add(book2); 35 bookShelf.add(book3); 36 bookShelf.remove(book3); 37 /* 38 for(var i=0; i<bookShelf.models.length; i++) { 39 alert(bookShelf.models[i].get('title')); 40 } 41 */ 42 //基于underscore这个js库,还可以使用each的方法获取collection中的数据 43 bookShelf.each(function(book){ 44 alert(book.get('title')); 45 }); 46 47 //2、使用fetch从服务器端获取数据,使用reset渲染 48 bookShelf.bind('reset', showAllBooks); 49 bookShelf.fetch({url:'/getbooks/',success:function(collection,response){ 50 collection.each(function(book){ 51 alert(book.get('title')); 52 }); 53 },error:function(){ 54 alert('error'); 55 }}); 56 showAllBooks = function(){ 57 bookShelf.each(function(book){ 58 //将book数据渲染到页面。 59 }); 60 } 61 //上述代码仅仅均为可正常执行的代码,不过关于服务器端的实例在后面会有。 62 })(jQuery); 63 </script> 64 </html>