基于Backbone.js的JavaScript MVC示例程序(6)
来源:互联网 发布:网络pos机套现安全吗 编辑:程序博客网 时间:2024/04/29 20:02
- 一.概述
- 二.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.3 修改User信息
界面如下,在右边 User 详细信息处增加了一个 "Edit" 按钮,点击之后下面的信息就变成了输入框,点击 "Submit" 完成修改,左侧列表随之更新。
想要实现点击"Edit"将右侧详细信息的变为可编辑有几种方法:
1. 创建一个 UserEditView 专门来显示修改User信息的表单;
2. 点击 "Edit" 之后,将 UserInfoView 所绑定的 HTML 模板换成一个表单;
3. Todos 这个例子里面给出了另外一种思路,它在 HTML 模板里面隐含了一个表单,默认情况下通过 css 将表单隐藏,点击 "Edit" 之后显示表单,并将非表单部分隐藏。
本例中采用了第三种方法。
3.html,在 user-info-template 模板中加入一个隐含的表单:
1 <!-- user-info-template中加入编辑User信息的表单 --> 2 <script type="text/template" id="user-info-template"> 3 <h3>User Information</h3> 4 <button id="edit">Edit</button> 5 <ul id="user-info"> 6 <li>ID:<span><%= id %></span></li> 7 <li>Username:<span><%= username %></span><input type="text" name="username" value="<%= username %>" /></li> 8 <li>Password:<span><%= password %></span><input type="password" name="password" value="<%= password %>" /></li> 9 <li>Email:<span><%= email %></span><input type="text" name="email" value="<%= email %>" /></li>10 <li>Phone:<span><%= phone %></span><input type="text" name="phone" value="<%= phone %>" /></li>11 <button id="edit-submit">Submit</button>12 </ul>13 </script>
mvc3.js
1 $(document).ready(function() { 2 3 var User = Backbone.Model.extend({ 4 }); 5 6 var UserList = Backbone.Collection.extend({ 7 ... //不变 8 }); 9 10 var UserItemView = Backbone.View.extend({11 tagName : "li",12 userItemTemplate : _.template($("#user-item-template").html()), 13 events : { 14 "click a" : "displayInfo",15 },16 initialize : function() { 17 //this.infoView = new UserInfoView({model : this.model}); //删除18 this.model.bind('change', this.render, this); //新增,修改成功后会触发19 },20 render : function() {21 this.$el.html(this.userItemTemplate(this.model.toJSON()));22 return this;23 },24 /*displayInfo : function() { 25 this.infoView.render();26 },*/27 displayInfo : function() { //修改,注释一28 if(_.isEmpty(infoView)){29 infoView = new UserInfoView({model : this.model});30 }else{31 infoView.model = this.model;32 infoView.model.unbind('change');33 infoView.model.bind('change', this.render, this);34 infoView.model.bind('change', infoView.render, infoView);35 }36 infoView.render();37 },38 });39 40 var UserInfoView = Backbone.View.extend({41 el : $("#right"),42 userInfoTemplate : _.template($("#user-info-template").html()),43 events : {44 "click #edit" : "displayEdit", //新增45 "click #edit-submit" : "submitEdit", //新增46 },47 initialize : function() {48 this.model.bind('change', this.render, this); //新增49 },50 render : function(){51 this.$el.html(this.userInfoTemplate(this.model.toJSON()));52 return this;53 },54 displayEdit : function() { //新增,改变 class,显示表单55 this.$("#user-info").addClass("editing");56 },57 submitEdit : function() { //新增,提交表单58 this.model.save({ //注释二59 "username":$("input[name='username']").val(),60 "password":$("input[name='password']").val(),61 "email":$("input[name='email']").val(),62 "phone":$("input[name='phone']").val(),63 });64 this.$("#user-info").removeClass("editing"); //改变 class,隐藏表单65 },66 });67 68 var UserListView = Backbone.View.extend({69 ... //不变70 });71 72 var userListView = new UserListView();73 var infoView; //新增74 });
注释一:
在上一节中,每一个 UserItemView 都与一个 UserInfoView 一一对应,在显示User详细信息的时候是没有问题的,但是在修改User信息的时候会出现问题。因为多个 UserInfoView 绑定到了同一个 "Submit" 按钮上,所以在点击 "Submit" 的时候可能会更新好几个 User 的信息。
解决的方法是声明一个全局的 UserInfoView(73行),在每一次点击列表中的 User 时,都将 UserInfoView 的 model 设置为当前点击的 User(31行),并且将当前的 UserItemView 和 UserInfoView 的 render() 方法绑定到这个 User 的 change 事件上(33-34行),并与之前的 User 解绑(32行),这样的话表单提交之后,左侧的列表和右侧的详细信息都会随之改变,而且也不会影响到其他 User。
不知道会不会有更好的方法,欢迎交流。
注释二:
官网上对 model.save() 方法的解释如下:
model.save([attributes], [options])
通过委托 Backbone.sync 保存模型到数据库(或可替代的持久层)。 attributes 散列表 (在 set) 应当包含想要改变的属性,不涉及的键不会被修改。 如果模型含有 validate 方法,并且验证失败,模型不会保存。 如果模型 isNew, 保存将采用 "create" (HTTP POST) 方法, 如果模型已经在服务器存在,保存将采用 "update" (HTTP PUT) 方法。
进一步看一下 isNew() 方法的解释:
model.isNew()
模型是否已经保存到服务器。 如果模型尚无 id,则被视为新的。
在这里,被修改的 User 已经有 id 了,因此调用 model.save() 的时候自动向服务器发出 PUT 请求,请求中包含除了 id 之外的4个 attributes。
Model 有一个 id,还有一个 cid,官方文档是这么说的:
- model.id 模型的特殊属性, id 可以是任意字符串(整型 id 或 UUID)。 在属性中设置的 id 会被直接拷贝到模型属性上。 我们可以从集合(collections)中通过 id 获取模型,另外 id 通常用于生成模型的 URLs。
- model.cid 模型的特殊属性,cid 或客户 id 是当所有模型创建时自动产生的唯一标识符。 客户 ids 在模型尚未保存到服务器之前便存在,此时模型可能仍不具有最终的 id, 客户 ids 的形式为:c1, c2, c3 ...
也就是说 id 需要我们设置好,url() 方法会根据 id 来生成 Model 的 URL,这个 id 需要与 Server 端的 id 对应上,这样才能完成 GET/PUT/DELETE 请求。而 cid 我们并不需要去管它,实际上我们可以发现 View 也是有 cid 的。
之前在 Server 端返回的 JSON 中,User 的信息中正好有个 id,我们试一试将 JSON 中的 id 换成 uid,会有什么反应。修改起来比较简单,只要把 com.demo.register.bean.User 的 id 属性改成 uid 就行了。我们可以发现,在页面提交 Edit 的表单之后,会发出 POST 请求,并新增一个 User,而不是修改了当前 User。再进一步查看 userList,发现里面的 User 都没有 id,所以 isNew() 的返回结果是 false,save() 的时候一直都是发出 POST 请求。
通过重载 url() 和 isNew() 方法可以解决这个问题,只要将对 id 的判断改成对 uid 的判断就行了:
1 // Default URL for the model's representation on the server -- if you're using Backbone's restful methods, override this to change the endpoint that will be called. 2 url: function() { 3 var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError(); 4 if (this.isNew()) return base; 5 return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id); 6 }, 7 //重载之后: 8 url: function() { 9 var base = this.collection.url ;10 if (this.isNew()) return base;11 return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.uid);12 },13 14 // A model is new if it has never been saved to the server, and lacks an id.15 isNew: function() {16 return this.id == null;17 },18 //重载之后:19 isNew: function() {20 return this.attributes.uid == null;21 },
当然这只是一个实验,最好还是不要去重载它,老老实实地使用 id 吧。
- 基于Backbone.js的JavaScript MVC示例程序(6)
- 基于Backbone.js的JavaScript MVC示例程序(1)
- 基于Backbone.js的JavaScript MVC示例程序(2)
- 基于Backbone.js的JavaScript MVC示例程序(3)
- 基于Backbone.js的JavaScript MVC示例程序(4)
- 基于Backbone.js的JavaScript MVC示例程序(5)
- 基于Backbone.js的JavaScript MVC示例程序(7)
- 基于Backbone.js的JavaScript MVC示例程序(8)
- 基于Backbone.js的JavaScript MVC示例程序(9)
- backbone.js的mvc
- JavaScript MVC框架backbone.js初探
- JS 的那些MVC 框架 の backbone
- JS MVC 框架(BackBone)
- JAVASCRIPT的MVC示例
- backbone.js MVC 架构解析
- 分享一个基于jQuery,backbone.js和underscore.js的消息提示框架 - Backbone.Notifier
- Backbone.js的集合
- javascript MVC框架之 Backbone 实用指南
- 基于Backbone.js的JavaScript MVC示例程序(1)
- 基于Backbone.js的JavaScript MVC示例程序(2)
- 基于Backbone.js的JavaScript MVC示例程序(3)
- 基于Backbone.js的JavaScript MVC示例程序(4)
- 基于Backbone.js的JavaScript MVC示例程序(5)
- 基于Backbone.js的JavaScript MVC示例程序(6)
- 基于Backbone.js的JavaScript MVC示例程序(7)
- 基于Backbone.js的JavaScript MVC示例程序(8)
- eclipse编译慢 提高eclipse的性能
- 基于Backbone.js的JavaScript MVC示例程序(9)
- Java 位运算符
- 修改狗日的联想K860的锁屏键
- [C++] 跨平台的生成GUID方法
- [Java][Tomcat]在eclipse中运行tomcat报的一个错误