HTML5技术

我对Backbone.js的一些认识 - 流云诸葛(6)

字号+ 作者:H5之家 来源:H5之家 2016-07-07 13:00 我要评论( )

想想如果把todos这个app,做成一个直接保存到数据库的应用,我们在增加一个todo的时候的逻辑是怎么样的?在官方给出的代码中,它的新增逻辑是,只要新的todo一保存就立即显示到todo列表里面去,根本都不判断是否有

想想如果把todos这个app,做成一个直接保存到数据库的应用,我们在增加一个todo的时候的逻辑是怎么样的?在官方给出的代码中,它的新增逻辑是,只要新的todo一保存就立即显示到todo列表里面去,根本都不判断是否有保存成功(当然一个localStorage的应用,也没有失败的情况吧)。如果考虑成一个直接保存的数据库应用,我想大部分人习惯的逻辑应该是这样的,先创建一个todo,然后调用异步请求持久化的数据库,并且给异步请求添加回调,只有根据响应判断请求成功之后,才往todo列表里面添加一个新的,具体代码就是这个样子:

createTodo: function (e) { var $new_input = this.$new_input, value = $.trim($new_input.val()); if (e.which == 13 && value) { td = new Todo({ text: value }, { //必须通过collection指定todo属于的集合,否则后面的save方法会报错 collection: this.todos }); _async = td.save({}, {wait: true}), that = this; _async && _async.done(function () { //保存成功后与用户交互 TipView.create({info: '新增成功', type: 'success'}).show(); //添加到todos,以便触发todos的add事件 that.todos.add(td); $new_input.focus().val(''); }); } }

另外Collection有提供一个create方法,相当于一步完成save和add的操作,这个方法不好,因为它的返回值不是一个xhr对象,不好添加回调,当然使用option.success是可以的,不过这种回调方式已经过时了,不符合现在的习惯了,所以我宁愿拆开来用,先save,再add,代码更清晰。

再来说删:

同样考虑保存到数据库时的删除场景,通常的逻辑应该是先发起删除的异步请求,等请求成功并判断删除成功后,再从界面上清除相关的dom内容。所以正确的做法应该是这样的:

clear: function (e) { _async = this.model.destroy({wait: true}); _async && _async.done(function () { TipView.create({info: '删除成功', type: 'success'}).show(); }); }

要特别注意那个wait: true选项,因为如果没有这个,model会立即触发destroy事件,有可能导致数据并没有从数据库删除成功,但是界面上已经看不到了,你再次刷新的时候又能看到。

最后说改:

其实改的问题跟前面的增删也差不多,主要是要注意异步请求的回调处理。还有一点要说明的是,wait: true这个选项,要准确使用,因为在有了这种数据驱动模式来修改DOM的时候,我们修改DOM的方式除了用户的输入,js代码直接操作DOM,还有js代码改变跟DOM相关的数据,导致数据的change,最终引起DOM的重新渲染。wait: true这个选项,会影响到我们能否保证model与view始终保持一致性,就是说model在某个状态的时候,view应该就是某个状态,而不是另外一个不相符的状态。什么情况下会导致这种不一致性,看下面的这个代码:

toggle: function () { .save('complete', !this.get('complete')); }

这个方法是todos应用里面,Todo类提供的一个实例方法,它是在点击todo列表上的单个todo项的复选框的时候被调用的:

toggle: function (e) { var _async = this.model.toggle(); _async && _async.done(function () { TipView.create({info: '修改成功', type: 'success'}).show(); }); },

这个代码是TodoView类上的一个实例方法,跟上面的toggle方法位置不同。由于点击todo列表上的单个todo项的复选框这个操作,引发的数据流向是从dom到model,所以当你点击一个没有完成的todo的时候,它的复选框会先勾上,然后你准备调用model.toggle方法,去把model的属性跟复选框的状态同步起来,假如你在model.toggle里面使用wait: true这个选项,那么model的属性同步就只能能到请求成功才行;但是在请求过程中,用户有可能有再次点击复选框的情况,请求也有失败的情况,最终可能会存在UI与model数据不一致的问题。

以上就是一些在做增删改的时候要注意问题,同时还得考虑一些交互的逻辑,这个也是必不可少的,在我前面给出的demo地址中,这些东西都有考虑进去。

5. 如何做批量操作

这个问题也是我当时比较苦恼的一个问题,backbone官方文档也说了,要不就自己写单独的ajax请求吧,好像现有的api方法也不支持批量操作。又得提到官方todos的问题了,官方todos在做批量处理的时候,是直接遍历调用各个todo的相关方法,来完成各个异步操作的,这在实际的工作中,能这么搞吗,得有多少个请求阿,一般批量处理无非就是把要改的东西的主键以数组的形式统一传递给后台,当然要修改的内容也得传递过去,就可以了。所以我是这么来完成todos里面的两个批量操作的:

toggleAll: function (e) { complete = this.$complete_all.find('input')[0].checked, data = []; this.todos.each(function (todo) { todo.set({complete: complete}); data.push(todo.toJSON()); todo.collection.localStorage.update(todo); }); //2. 发送异步请求批量更新 $.ajax({ url: '',//这里应该是真实的批量修改的接口地址 data: { data: JSON.stringify(data) } }).done(function(){ TipView.create({info: '批量更新成功!', type: 'success'}).show(); }); }, clearCompleted: function () { data = [],completes = this.todos.getComplete(); completes.forEach(function (todo) { data.push(todo.id); }); //2. 发送异步请求批量删除 $.ajax({ url: '',//这里应该是真实的批量删除的接口地址 data: { ids: JSON.stringify(data) } }).done(function(){ TipView.create({info: '批量删除成功!', type: 'success'}).show(); completes.forEach(function (todo) { todo.collection.localStorage.destroy(todo); //清空todo的内容,让backbone认为它是一个新创建的对象,以便在下一步调用destroy的时候不会发送请求! todo.clear({slient: true}); todo.destroy(); }); }); }

要注意这个批量代码中,有一部分代码在真实的环境下,应该是不需要的,因为我这里只是对真实场景的模拟,如果不加那些代码,我批量修改的数据,就无法持久化到localStorage里面了。

6. 总结

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖湾

    【react学习】关于react框架使用的一些细节要点的思考 - 外婆的彭湖

    2017-04-16 18:00

  • 使用phonegap获取设备的一些信息 - ganchuanpu

    使用phonegap获取设备的一些信息 - ganchuanpu

    2017-03-30 13:00

  • 微信H5页面遇到的一些问题 - 乖乖脸很大

    微信H5页面遇到的一些问题 - 乖乖脸很大

    2017-01-27 08:05

  • 微信小程序开闸,关于入口、推广、场景的一些观察与思考 - 腾讯攻城师lee

    微信小程序开闸,关于入口、推广、场景的一些观察与思考 - 腾讯攻城

    2017-01-10 13:00

网友点评
4