RequireJS與Backbone簡單整合

前言

昨天咱們一塊兒學習了Backbone,最後作了一個備忘錄的例子,說是作了不如說是看了下官方提供的例子,因此最終我感受咱們仍是沒能掌握Backbone,今天還得作個其它例子先。javascript

而後前面也只是草草學習了RequireJS,沒作demo,這個週末又在看電影打遊戲睡覺瞎折騰,轉眼就週日下午了,忽然詩性大起,因而做詩一首先:html

古有通宵看A片,今有徹夜碼代碼java

好吧,咱們開始今天的學習吧,咱們今天先用backbone作一個通信錄的東西,而後使用requireJS組裝之。jquery

部分參考:the5fire的技術博客git

簡單例子

作以前咱們先來個簡單的例子:github

 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給出的例子,我和個人小夥伴一下都明白了。。。。web

以上代碼涉及到Backbone三個部分:View、Model、Collection,咱們在addOne裏面使用了jquery綁定dom之後會將之消除。ajax

各位請看這個代碼:api

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     //一、一個簡單的例子
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     //二、使用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>
完整參考代碼

Router(以前好像沒看到)

以前咱們學習的時候好像錯過了Router了,路由的出現是想控制URL呢,Backbone.Router會把#標籤當作url路徑。

 1 <html>
 2 <head>
 3     <title>the5fire-backbone-router</title>
 4 </head>
 5 <body>
 6     <a href="#/posts/120">Post 120</a>
 7 <a href="#/download/user/images/hey.gif">download gif</a>
 8 <a href="#/dashboard/graph">Load Route/Action View</a>
 9 </body>
10 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
11     <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
12     <script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
13     <script>
14     (function ($) {
15         //Backbone中的router,見名知意,router有路由的意思,顯然這裏是要控制url的。
16         //Backbone.Router會把你鏈接中的#標籤當作是url路徑
17         /**
18         //一、來看一個簡單的例子
19         var AppRouter = Backbone.Router.extend({
20             routes: {
21                 "*actions" : "defaultRoute"
22             },
23             defaultRoute : function(actions){
24                 alert(actions);
25             }
26         });
27 
28         var app_router = new AppRouter;
29 
30         Backbone.history.start();
31 
32 
33         //二、既然是對url進行匹配那麼它應該不只僅只是簡單的靜態匹配,應該具備傳遞參數的功能,因此下面再來一個動態的router的例子.
34         var AppRouter = Backbone.Router.extend({
35             routes: {
36                 "/posts/:id" : "getPost",
37                 "*actions" : "defaultRoute"
38             },
39             getPost: function(id) {
40                 alert(id);
41             },
42             defaultRoute : function(actions){
43                 alert(actions);
44             }
45         });
46 
47         var app_router = new AppRouter;
48 
49         Backbone.history.start();
50         **/
51         //從上面已經能夠看到匹配#標籤以後內容的方法,有兩種:一種是用「:」來把#後面的對應的位置做爲參數;還有一種是「*」,它能夠匹配全部的url,下面再來演練一下。
52         var AppRouter = Backbone.Router.extend({
53             routes: {
54                 "/posts/:id" : "getPost",
55                 "/download/*path": "downloadFile",  //對應的連接爲<a href="#/download/user/images/hey.gif">download gif</a>
56                         "/:route/:action": "loadView",      //對應的連接爲<a href="#/dashboard/graph">Load Route/Action View</a>
57                 "*actions" : "defaultRoute"
58             },
59             getPost: function(id) {
60                 alert(id);
61             },
62             defaultRoute : function(actions){
63                 alert(actions);
64             },
65             downloadFile: function( path ){
66                 alert(path); // user/images/hey.gif
67             },
68             loadView: function( route, action ){
69                 alert(route + "_" + action); // dashboard_graph
70             }
71         });
72 
73         var app_router = new AppRouter;
74 
75         Backbone.history.start();
76 
77     })(jQuery);
78     </script>
79 
80 </html>
路由的例子

咱們暫時無論這個,不然任務完成不了了。

View

這個看完,咱們就要繼續今天的學習了,這裏用了太多時間啦。

backbone的view是用來顯示model數據到頁面的,同時監聽dom事件並相應變化。

來看看咱們的頁面主體:

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4 </head>
 5 <body>
 6     <div id="search_container">
 7     </div>
 8     <script type="text/template" id="search_template">
 9         <label><%= search_label %></label>
10         <input type="text" id="search_input" />
11         <input type="button" id="search_button" value="Search" />
12     </script>
13 </body>
14 <script src="js/jquery.js" type="text/javascript"></script>
15 <script src="js/underscore.js" type="text/javascript"></script>
16 <script src="js/backbone.js" type="text/javascript"></script>
17 <script type="text/javascript">
18     (function ($) {
19         //此處添加下面的試驗代碼
20     })(jQuery);
21 </script>
22 </html>

el屬性

該屬性引用dom中的一些元素,每一個view都會有這個屬性,沒有聲明就默認建立空div

(function ($) {
    SearchView = Backbone.View.extend({
        initialize: function () {
            //this.render();
        },
        render: function () {
            //使用underscore這個庫,來編譯模板
            var template = _.template($("#search_template").html(), {});
            //加載模板到對應的el屬性中
            //this.el.html(template);   //感謝 子不語同窗指正。
            $(this.el).html(template);
        }
    });
    var searchView = new SearchView({ el: $("#search_container") });
    searchView.render();  //這個reander的方法能夠放到view的構造函數中
})(jQuery);

[這裏有一個錯誤,由於這個例子裏沒有傳入search_label這個變量,因此你運行的時候要把html的模板中的那個變量改掉才行。]

事件綁定

(function ($) {
    SearchView = Backbone.View.extend({
        initialize: function () {
            this.render();
        },
        render: function () {
            //使用underscore這個庫,來編譯模板
            var template = _.template($("#search_template").html(), {});
            //加載模板到對應的el屬性中
            //this.el.html(template);
            $(this.el).html(template);
        },
        events: {  //就是在這裏綁定的
            'click input[type=button]': 'doSearch'  //定義類型爲button的input標籤的點擊事件,觸發函數doSearch
        },

        doSearch: function (event) {
            alert("search for " + $("#search_input").val());
        }
    });
    var searchView = new SearchView({ el: $("#search_container") });
})(jQuery);

模板

此處的模板,就是以數據替換其中的特殊標籤<%= search_label %>

 1 <html xmlns="http://www.w3.org/1999/xhtml">
 2 <head>
 3     <title></title>
 4 </head>
 5 <body>
 6     <div id="search_container">
 7     </div>
 8     <script type="text/template" id="search_template">
 9         <label><%= search_label %></label>
10         <input type="text" id="search_input" />
11         <input type="button" id="search_button" value="Search" />
12     </script>
13 </body>
14 <script src="js/jquery.js" type="text/javascript"></script>
15 <script src="js/underscore.js" type="text/javascript"></script>
16 <script src="js/backbone.js" type="text/javascript"></script>
17 <script type="text/javascript">
18     (function ($) {
19         SearchView = Backbone.View.extend({
20             initialize: function () {
21                 this.render('the5fire');
22             },
23             render: function (search_label) {
24                 //使用underscore這個庫,來編譯模板
25                 var template = _.template($("#search_template").html(), { search_label: search_label });
26                 //加載模板到對應的el屬性中
27                 $(this.el).html(template);
28             },
29             events: {  //就是在這裏綁定的
30                 'click input[type=button]': 'doChange'
31             },
32             doChange: function (event) {
33                 //經過model發送數據到服務器
34                 this.render('the5fire' + $("#search_input").val());
35             }
36         });
37         var searchView = new SearchView({ el: $("#search_container") });
38     })(jQuery);
39 </script>
40 </html>

階段總結

好了,知識回顧暫時到這裏,咱們要來咱們的東西了,否則搞不完了。

HTML結構

有點一頭霧水的感受,因而先上一張圖吧:

 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             <label>
17                 姓名:<input type="text" id="name" /></label>
18             <label>
19                 電話:<input type="text" id="phone" /></label>
20             <input type="button" value="保存" id="add" />
21         </div>
22     </div>
23 </body>
24 </html>

下面的輸入框用以新建通信項目,contact-list用以顯示通信錄列表。整個頁面很是簡單,咱們先就完成這個功能便可。

模型與集合

完了咱們應該建立Contact模型了,咱們先來隨便寫寫代碼看看有神馬狀況發生:

var Contact = Backbone.Model.extend({
    validate: function (attr) {
        if (!attr.name || attr.name.length > 5) {
            return '姓名格式錯誤';
        }
    }
});
var contact = new Contact();
var s = '';

這裏根據backbone的Model的extend方法創建了Contact模型。

其中可能會有驗證機制,我這裏隨便寫了一個,電話其實也須要驗證的。

而模型會有的方法,咱們暫時無論他了,先來個集合吧:

<script src="js/underscore.js" type="text/javascript"></script>
<script src="js/backbone.js" type="text/javascript"></script>
<script src="js/backbone.localStorage.js" type="text/javascript"></script>
<script type="text/javascript">
var Contact = Backbone.Model.extend({
    validate: function (attr) {
        if (!attr.name || attr.name.length > 5) {
            return '姓名格式錯誤';
        }
    }
});

var ContackList = Backbone.Collection.extend({
    model: ContackList,
    localStorage: new Store('contacts')//全部信息保存至contacts空間下,注意這次用到了本地存儲的東西
});
var s = '';
</script>

這裏使用了本地存儲,因此咱們必須設置localStorage屬性。

視圖

如今咱們來設置視圖後:

 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             <label>
17                 姓名:<input type="text" id="name" /></label>
18             <label>
19                 電話:<input type="text" id="phone" /></label>
20             <input type="button" value="保存" id="add" />
21         </div>
22     </div>
23 </body>
24 <script src="js/jquery.js" type="text/javascript"></script>
25 <script src="js/underscore.js" type="text/javascript"></script>
26 <script src="js/backbone.js" type="text/javascript"></script>
27 <script src="js/backbone.localStorage.js" type="text/javascript"></script>
28 <script type="text/javascript">
29     (function ($) {
30         var Contact = Backbone.Model.extend({
31             validate: function (attr) {
32                 if (!attr.name || attr.name.length > 5) {
33                     return '姓名格式錯誤';
34                 }
35             }
36         });
37 
38         var ContackList = Backbone.Collection.extend({
39             model: ContackList,
40             localStorage: new Store('contacts'), //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西
41             initialize: function (models, options) {
42                 this.bind('add', options.view.add);
43             }
44         });
45         var AppView = Backbone.View.extend({
46             el: $('body'),
47             tmplate: _.template('<li><%= name %>:<%= phone %></li>'),
48 
49             initialize: function () {
50                 _.bindAll(this, 'save', 'add');
51                 this.contacts = new ContackList(null, { view: this });
52                 this.list = $('#contact-list');
53                 this.name = $('#name');
54                 this.phone = $('#phone');
55             },
56             events: {
57                 'click #add': 'save'
58             },
59             save: function () {
60                 var model = new Contact({ name: this.name.val(), phone: this.phone.val() });
61                 this.contacts.add(model);
62             },
63             add: function (model) {
64                 var obj = model.toJSON();
65                 $(this.list).append(this.tmplate(obj));
66             }
67         });
68         var app = new AppView();
69 
70     })(jQuery);
71 </script>
72 </html>

咱們的簡單的界面終於出來了。。。。因而咱們來優化加功能吧:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <title></title>
  5 </head>
  6 <body>
  7     <div id="contactapp">
  8         <header>
  9             <h1>
 10                 通信錄</h1>
 11         </header>
 12         <section id="main">
 13             <ul id="contact-list">
 14             </ul>
 15         </section>
 16         <div class="create">
 17             <label>
 18                 姓名:<input type="text" id="name" /></label>
 19             <label>
 20                 電話:<input type="text" id="phone" /></label>
 21             <input type="button" value="保存" id="add" />
 22         </div>
 23     </div>
 24 </body>
 25 <script src="js/jquery.js" type="text/javascript"></script>
 26 <script src="js/underscore.js" type="text/javascript"></script>
 27 <script src="js/backbone.js" type="text/javascript"></script>
 28 <script src="js/backbone.localStorage.js" type="text/javascript"></script>
 29 <script type="text/javascript">
 30     (function ($) {
 31         var Contact = Backbone.Model.extend({
 32             initialize: function () {
 33                 this.bind("error", function (model, error) {
 34                     alert(error);
 35                 });
 36             },
 37             validate: function (attr) {
 38                 if (attr.name.length == '') {
 39                     return '姓名格式錯誤';
 40                 }
 41             }
 42         });
 43         var ContactList = Backbone.Collection.extend({
 44             model: Contact,
 45             localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西
 46 
 47         });
 48         var list = new ContactList();
 49         var ContactView = Backbone.View.extend({
 50             tagName: 'li',
 51             template: _.template('<div><%= name %>:<%= phone %></div>'),
 52             events: {
 53                 'click li': 'test'
 54             },
 55             initialize: function () {
 56                 _.bindAll(this, 'render', 'remove');
 57                 this.model.bind('change', this.render);
 58                 this.model.bind('destroy', this.remove);
 59             },
 60             render: function () {
 61                 var html = this.template(this.model.toJSON());
 62                 //this.el是生成的空div
 63                 $(this.el).html(html);
 64                 //返回了當前視圖
 65                 return this;
 66             },
 67             remove: function () {
 68                 $(this.el).remove();
 69             },
 70             test: function () {
 71                 alert(this);
 72                 var s = '';
 73             }
 74         });
 75         var AppView = Backbone.View.extend({
 76             el: $('body'),
 77             events: {
 78                 'click #add': 'save'
 79             },
 80             initialize: function () {
 81                 this.name = this.$('#name');
 82                 this.phone = this.$('#phone');
 83                 this.list = this.$('#contact-list');
 84 
 85                 _.bindAll(this, 'render', 'add', 'loadList', 'save');
 86                 //爲集合綁定事件
 87                 list.bind('add', this.add);
 88                 //添加修改時觸發
 89                 list.bind('refresh', this.loadList);
 90                 list.fetch();
 91             },
 92             //添加項目
 93             add: function (model) {
 94                 var view = new ContactView({ model: model });
 95                 this.list.append(view.render().el);
 96 //                view.model.save({ name: model.name, phone: model.phone });
 97                 var s = '';
 98             },
 99             loadList: function () {
100                 list.each(this.add);
101             },
102             save: function () {
103                 var name = this.name.val();
104                 var phone = this.phone.val();
105                 list.create({ name: name, phone: phone });
106                 this.name.val('');
107                 this.phone.val('');
108             }
109         });
110         var app = new AppView();
111 
112     })(jQuery);
113 </script>
114 </html>

這個代碼與上述代碼有些不一樣,咱們來理一理:

① 模型與集合變化不大

② 具備2個視圖:

通信錄視圖,咱們後面通信錄會有編輯、刪除或者其餘功能,就在此上寫

全局視圖,AppView用於全局,可能還會顯示總體狀態。

③流程

由於咱們只有一個通信錄列表,因此將之全局化出來了:

var list = new ContactList();

ContactView主要關注自身,與總體能夠隔離開。

tagName指定了造成的dom的外層結構,不指定就是div

template會解析模板,我直接寫到這裏了,後面咱們作點修改給個刪除功能

template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;">[刪除]</a></div>'),

events就是綁定的事件

PS:具體代碼各位本身看吧......

這裏將刪除事件加上就算階段完成了:

  1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml">
  3 <head>
  4     <title></title>
  5 </head>
  6 <body>
  7     <div id="contactapp">
  8         <header>
  9             <h1>
 10                 通信錄</h1>
 11         </header>
 12         <section id="main">
 13             <ul id="contact-list">
 14             </ul>
 15         </section>
 16         <div class="create">
 17             <label>
 18                 姓名:<input type="text" id="name" /></label>
 19             <label>
 20                 電話:<input type="text" id="phone" /></label>
 21             <input type="button" value="保存" id="add" />
 22         </div>
 23     </div>
 24 </body>
 25 <script src="js/jquery.js" type="text/javascript"></script>
 26 <script src="js/underscore.js" type="text/javascript"></script>
 27 <script src="js/backbone.js" type="text/javascript"></script>
 28 <script src="js/backbone.localStorage.js" type="text/javascript"></script>
 29 <script type="text/javascript">
 30     (function ($) {
 31         var Contact = Backbone.Model.extend({
 32             initialize: function () {
 33                 this.bind("error", function (model, error) {
 34                     alert(error);
 35                 });
 36             },
 37             validate: function (attr) {
 38                 if (attr.name.length == '') {
 39                     return '姓名格式錯誤';
 40                 }
 41             }
 42         });
 43         var ContactList = Backbone.Collection.extend({
 44             model: Contact,
 45             localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西
 46 
 47         });
 48         var list = new ContactList();
 49         var ContactView = Backbone.View.extend({
 50             tagName: 'li',
 51             template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;" class="delete">[刪除]</a></div>'),
 52             events: {
 53                 'click .delete': 'destroy'
 54             },
 55             initialize: function () {
 56                 _.bindAll(this, 'render', 'remove');
 57                 this.model.bind('change', this.render);
 58                 this.model.bind('destroy', this.remove);
 59             },
 60             render: function () {
 61                 var html = this.template(this.model.toJSON());
 62                 //this.el是生成的空div
 63                 $(this.el).html(html);
 64                 //返回了當前視圖
 65                 return this;
 66             },
 67             destroy: function () {
 68                 this.model.destroy();
 69             },
 70             remove: function () {
 71                 $(this.el).remove();
 72 
 73             }
 74         });
 75         var AppView = Backbone.View.extend({
 76             el: $('body'),
 77             events: {
 78                 'click #add': 'save'
 79             },
 80             initialize: function () {
 81                 this.name = this.$('#name');
 82                 this.phone = this.$('#phone');
 83                 this.list = this.$('#contact-list');
 84 
 85                 _.bindAll(this, 'render', 'add', 'loadList', 'save');
 86                 //爲集合綁定事件
 87                 list.bind('add', this.add);
 88                 //添加修改時觸發
 89                 list.bind('refresh', this.loadList);
 90                 list.fetch();
 91             },
 92             //添加項目
 93             add: function (model) {
 94                 var view = new ContactView({ model: model });
 95                 this.list.append(view.render().el);
 96                 //                view.model.save({ name: model.name, phone: model.phone });
 97                 var s = '';
 98             },
 99             loadList: function () {
100                 list.each(this.add);
101             },
102             save: function () {
103                 var name = this.name.val();
104                 var phone = this.phone.val();
105                 list.create({ name: name, phone: phone });
106                 this.name.val('');
107                 this.phone.val('');
108             }
109         });
110         var app = new AppView();
111 
112     })(jQuery);
113 </script>
114 </html>
帶刪除功能的通信錄

階段總結

咱們又簡單的回顧了下backbone,此次學習後我和個人小夥伴表示都懂了。。。。

整合requireJS

先上個圖:

尼瑪,一下多出了好多文件:

模型

define(function () {
    var Contact = Backbone.Model.extend({
        initialize: function () {
            this.bind("error", function (model, error) {
                alert(error);
            });
        },
        validate: function (attr) {
            if (attr.name.length == '') {
                return '姓名格式錯誤';
            }
        }
    });
    return Contact;
});

集合

define(['model/contact'], function (Contact) {
    var ContactList = Backbone.Collection.extend({
        model: Contact,
        localStorage: new Store('contacts') //全部信息保存至contacts空間下,注意這次用到了本地存儲的東西

    });
    return ContactList;
});

contact視圖

define(function () {
    var ContactView = Backbone.View.extend({
        tagName: 'li',
        template: _.template('<div><%= name %>:<%= phone %><a href="javascript:;" class="delete">[刪除]</a></div>'),
        events: {
            'click .delete': 'destroy'
        },
        initialize: function () {
            _.bindAll(this, 'render', 'remove');
            this.model.bind('change', this.render);
            this.model.bind('destroy', this.remove);
        },
        render: function () {
            var html = this.template(this.model.toJSON());
            //this.el是生成的空div
            $(this.el).html(html);
            //返回了當前視圖
            return this;
        },
        destroy: function () {
            this.model.destroy();
        },
        remove: function () {
            $(this.el).remove();

        }
    });
    return ContactView;
});

全局視圖

define(['collection/contact', 'view/contact'], function (contact, ContactView) {
    window.list = new contact();
    var AppView = Backbone.View.extend({
        el: $('body'),
        events: {
            'click #add': 'save'
        },
        initialize: function () {
            this.name = this.$('#name');
            this.phone = this.$('#phone');
            this.list = this.$('#contact-list');

            _.bindAll(this, 'render', 'add', 'loadList', 'save');
            //爲集合綁定事件
            list.bind('add', this.add);
            //添加修改時觸發
            list.bind('refresh', this.loadList);
            list.fetch();
        },
        //添加項目
        add: function (model) {
            var view = new ContactView({ model: model });
            this.list.append(view.render().el);
            //                view.model.save({ name: model.name, phone: model.phone });
            var s = '';
        },
        loadList: function () {
            list.each(this.add);
        },
        save: function () {
            var name = this.name.val();
            var phone = this.phone.val();
            list.create({ name: name, phone: phone });
            this.name.val('');
            this.phone.val('');
        }
    });
    return AppView;
});

main函數

require.config({
    paths: {
        jquery: 'js/jquery',
        underscore: 'js/underscore',
        backbone: 'js/backbone',
        bl: 'js/backbone.localStorage'

    }
});

require(['jquery', 'underscore', 'backbone', 'bl', 'model/contact', 'collection/contact', 'view/contact', 'view/app'], 
function ($, _, b, bl, model, collection, view, app) {
    var app = new app();
});

HTML頁面

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <div id="contactapp">
        <header>
            <h1>
                通信錄</h1>
        </header>
        <section id="main">
            <ul id="contact-list">
            </ul>
        </section>
        <div class="create">
            <label>
                姓名:<input type="text" id="name" /></label>
            <label>
                電話:<input type="text" id="phone" /></label>
            <input type="button" value="保存" id="add" />
        </div>
    </div>
</body>
<script src="js/require.js" data-main="main" type="text/javascript"></script>
</html>

因而,咱們功能完成了:

結語

我和個人小夥伴說,尼瑪終於搞完了。。。。。。

相關文章
相關標籤/搜索