您的位置:首页 > Web前端 > JavaScript

基于Backbone.js的JavaScript MVC示例程序(4)

2013-10-29 14:54 211 查看
一.概述
二.REST Server的实现
2.1 REST API设计
2.2 数据库设计
2.3 用MyBatis实现的DAO层
2.4 用Jersey实现的REST API
2.5 用Spring AOP实现的日志功能
三.前端的实现
3.1 显示User列表
3.2 显示User详细信息
3.3 修改User信息
3.4 增加User
3.5 删除User
3.6 添加validate

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行)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: