zoukankan      html  css  js  c++  java
  • 基于Backbone.js的JavaScript MVC示例程序(4)

    3.1 显示User列表

    界面如下:

    1.html文件

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     3 <html>
     4 <head>
     5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     6 <script src="./js/jquery.js"></script>
     7 <script src="./js/underscore.js"></script>
     8 <script src="./js/backbone.js"></script>
     9 <script src="./js/mvc1.js"></script><!-- 引入js文件 -->
    10 <script type="text/template" id="user-item-template"><!-- html模板 -->
    11     <span>(<%= id %>)</span><a href="#"><%= username %></a>
    12 </script>
    13 <link rel="stylesheet" type="text/css" href="./css/default.css" />
    14 <title>MVC 1</title>
    15 </head>
    16 <body>
    17     <div id="main">
    18         <div id="left">
    19             <h3></h3>
    20             <ul id="user-list"></ul>
    21         </div>
    22         <div id="right"></div>
    23     </div>
    24 </body>
    25 </html>

     mvc1.js文件

     1 $(document).ready(function() { //注释一
     2     
     3     //定义User
     4     var User = Backbone.Model.extend({
     5     });
     6     
     7     //定义UserList,是User的集合
     8     var UserList = Backbone.Collection.extend({
     9         model : User,
    10         url : "/backbone-sample/rest/user", //注释二
    11         /*****重载fetch****
    12         fetch : function() {
    13             var self = this;
    14             $.ajax({
    15                 url: self.url,
    16                 cache:false,
    17                 type: 'GET',
    18                 async: true,
    19                 dataType: 'json',
    20                 timeout: 300000,
    21                 success: function( data, textStatus ) {                            
    22                     self.reset(data.user);
    23                 },        
    24             });
    25         }
    26         *************/
    27     });
    28     
    29     //定义UserItemView,用来显示用户列表中的一个条目
    30     var UserItemView = Backbone.View.extend({
    31         tagName : "li",
    32         userItemTemplate : _.template($("#user-item-template").html()), //绑定模板
    33         render : function() {
    34             this.$el.html(this.userItemTemplate(this.model.toJSON()));
    35             return this;
    36         },
    37     });
    38     
    39     //定义UserListView,用来显示用户列表
    40     var UserListView = Backbone.View.extend({
    41         el : $("#main"),
    42         initialize : function() {
    43             this.userList = new UserList();
    44             this.userList.bind('reset', this.addAll, this);
    45             this.userList.bind('all', this.render, this); //注释三
    46             this.userList.fetch({silent: true, success:function(collection, response){ //注释四
    47                 if(response != null){
    48                     collection.reset(response.user);
    49                 }else{
    50                     userListView.render();
    51                 }
    52             }});
    53         },
    54         render : function() {
    55             this.$("#left h3").html("Total Number:"+this.userList.length);
    56         },
    57         addOne : function(user) {
    58             var view = new UserItemView({model : user});
    59             this.$("#user-list").append(view.render().el);
    60         },
    61         addAll : function() { 
    62             this.userList.each(this.addOne);
    63         },
    64     });
    65     
    66     var userListView = new UserListView();//注释五
    67 });

     注释一:

    一开始列表内容显示不出来,找了半天没找到原因,后来才发现是忘记加document.ready了。

    注释二:

    Model 里面各有一个 url() 方法,和一个 urlRoot 属性;Collection 里面有一个 url() 方法,它们的关系如下:

    model.url() 返回模型资源在服务器上位置的相对 URL,默认的的实现是:如果模型包含在某个集合中,则生成 URL 的形式为:"/[collection.url]/[id]"; 如果模型不是集合的一部分,则 URL 形式为:"/[urlRoot]/id"。当然可以自己重载这个方法。

    例如:一个 id 为101的模型,存储在url为 "/documents/7/notes" 的 Colletion 中, 那么该模型的 URL 为:"/documents/7/notes/101"。

    一般 GET、PUT、DELETE 是对某个特定模型的操作,会用 model.url() 得到带有 id 的模型 URL;而 POST 操作是不知道模型id的,因此会用 collection.url() 得到集合的 URL。

    在本例中,User 包含在 UserList 中,因此需要指定 UserList 的 url。

    注释三:

    官网上对于bind方法的解释:object.bind(event, callback, [context])

    绑定 callback 函数到 object 对象。 当事件触发时执行回调函数 callback 。如果一个页面中有大量不同的事件,按照惯例使用冒号指定命名空间:"poll:start"或"change:selection"。当 callback 执行时提供第三个可选参数,可以为 this 指定上下文: model.bind(‘change’, this.render, this)绑定到特殊事件 "all" 的回调函数会在任意事件发生时被触发,其第一个参数为事件的名称。

    注意到第三个参数,指定了第二个参数中this所代表的对象,例如:如果把this.userList.bind('add', this.addOne, this)的this去掉,那么实际执行的时候,this.addOne中的this会是userList,实际上应该是userListView,于是就会出错。

    还有一点,在Todos这个例子中,所有的事件都是使用on来绑定事件的,也就是this.userList.on('add', this.addOne, this),我试了一下,二者没有什么区别。查了一下源码,on是定义在Backbone.Events中的一个函数,暂时还没能理解为什么二者是等价的。

    on: function(events, callback, context) {…} // Bind one or more space separated events, `events`, to a `callback` function. Passing `"all"` will bind the callback to all events fired.

    注释四:

    官网上对于Collection的fetch函数的解释如下:collection.fetch([options]) 

    从服务器拉取集合的默认模型,成功接收数据后会重置(reset)集合。options 支持 success 和 error 回调函数,回调函数接收 (collection, response) 作为参数。 可以委托 Backbone.sync 在随后处理个性化需求。处理 fetch 请求的服务器应当返回模型的 JSON 数组。

    也就是调用 UserList 的 fetch() 方法时,会自动对 model.url() 的地址发出GET请求,然后将接收到的 JSON 数组作为参数来调用 reset() 方法自动设置UserList里面的User数组。

    在我Server端,返回的Userlist格式如下:

    {"user":[{"id":"63","username":"Andy0011","password":"123123","email":"111111@1.com","phone":""},…]}

     注意到最外面会有一个 "user",这样的格式不能被默认的fetch函数使用来给集合设值,因此需要自己重载fetch函数。

    有两个方法来实现:

    第一个方法是在调用fetch函数的时候使用success回调函数,如注释四 fetch() 中的代码块所示。

    注意到有一个 silent: true,这是因为 fetch() 是异步的,当运行完之后自动触发 reset 事件来给 userList 赋值,但是这个时候服务器端的JSON还没有返回来,所以会报错。加上 silent: true 之后,就不会自动触发reset事件了,而是在success回调函数中使用 response.user 作为参数手动调用reset函数来给userList赋值。当然如果数据库里面是空的就会返回空,因此需要判断一下,区分处理。

    第二个方法更加灵活了,是在var UserList = Backbone.Collection.extend({ })这个里面重载fetch函数,如11-26行注释中的代码块所示。

    这是一个典型的jQuery ajax调用,将请求设置为同步是为了解决上面那个silent: true的问题。

    注释五:

    需要初始化一个 UserListView 类型的对象,页面显示的流程是:

    调用 UserListView 的 initialize() 方法(42行),在其中将2个方法绑定到了 userList 的事件上(44-45行),并调用了 userList 的 fetch() 放来从Server 获取数据并给其赋值(46行),在赋值的时候调用了 userList 的 reset() 方法(48行),这时候会触发已绑定的 "reset" 事件,并调用 UserListView 的 addAll() 方法显示列表内容,同时也会触发 "all" 事件,并调用UserListView 的 render() 方法在列表头部现实列表长度。在 addAll() 方法中为userList中的每一个元素调用 addOne() 方法(57行),在 addOne() 方法中会创建一个 UserItemView 并用它显示列表的一个条目(61行)。

        

  • 相关阅读:
    idea-----Intellij IDEA配置tomcat(非maven项目)
    idea-----idea的项目中output框出现乱码
    mysql on windows的安装
    maven配置
    安装tomcat8.5
    jdk11.0.2安装
    idea创建maven web项目
    Mac下使用sshpass让iterm2支持多ssh登录信息保存
    iterm 2快捷键
    java 8 Base64用法
  • 原文地址:https://www.cnblogs.com/hiddenfox/p/2646520.html
Copyright © 2011-2022 走看看