Backbone精髓,观察者模式和事件

前言

本人并不是专业的前端,只是因为须要被迫转作一段时间的前端,一段时间以来开始探索javascript上的MVC模式,最终打算从Backbone下手。在实战了一段时间之后,对Backbone有了一些我的的理解,记录在这里。不过,MVC是讲烂掉的话题了,本文并不讨论。原文:Backbone精髓,观察者模式和事件javascript

UI交互逻辑更须要设计模式

设计模式将人们在以往的开发过程当中的经验加以总结,以指导后人。然而,本人从事web后端开发的几年间,所使用到的设计模式其实很单一,无非就是工厂模式、单例模式、依赖反转。而更多的模式已经被开发框架所实现,程序员要作到仅仅是写几个if-elsefor以实现业务逻辑。那么真正须要设计模式的地方在哪里呢?翻遍设计模式的书,可发现其中的例子基本上是用户界面实现、编译器实现,不少高深的模式都在这些应用中得以体现。html

注意到如今web应用愈来愈多,而传统的客户端应用愈来愈少(除app以外),而人们对web程序的用户体验要求也是愈来愈高,传统的表单提交、页面刷新、重定向等用户交互方式愈来愈不被用户买帐。所以,javascript的历史地位空前的高,而且,围绕javascript,产生了大量的库和框架方便基于浏览器开发用户交互,甚至提出了javascript MVC思想,诸多的框架在javascript层面上实现了MVC模式。前端

观察者模式

其实,我的认为UI交互逻辑最须要的是MV模式,即模型和视图的关联,至于控制器,无关紧要。而M和V之间的实现关联的重要设计模式之一就是观察者模式,即因为视图呈现的复杂和多样化,为了便于扩展,须要视图有一种随模型数据的变化而“自行变化”的能力,而实现方式就是,视图经过侦听模型对象的变化而渲染本身,不须要外力来渲染,外力只须要改变惟一的标准--模型对象就能够了。java

Backbone的事件

根据上面讨论,要实现观察者模式,事件是很是重要的机制。在浏览器和javascript中,原生的事件是浏览器实现的基于DOM的事件体系。然而,这在咱们须要的M和V的观察者模式中是不够的。幸亏,Backbone实现了这样的机制。有了它,可以让任何javascript对象拥有“事件能力”,来看看是如何作到的:程序员

你可能没有注意过Backbone.Events就是事件实现的核心,它可让对象拥有事件能力web

var Events = Backbone.Events = { .. }

那么具体的看,事件能力究竟包含哪些能力呢?咱们简单的来看一下:后端

listenTo: function(obj, name, callback)

使当前对象侦听obj对象的一个叫name的事件,当事件被触发后,回调callback设计模式

listenToOnce: function(obj, name, callback)

使当前对象侦听obj对象的一个叫name的事件,当事件被触发后,回调callback一次(之后不会在回调)数组

trigger: function(name)

当前对象触发name事件浏览器

看下面的实验下面的代码:

var model = _.extend({},Backbone.Events);
var view = _.extend({},Backbone.Events);
view.listenTo(model,'custom_event',function(){ alert('catch the event') });
model.trigger('custom_event');

能够在jsfiddle上实验这个代码,结果以下:

能够看到,依靠Backbone.Events是能够实现观察者模式的。由于对于上面代码的model对象而言,它并不知道view对象在侦听它,甚至能够有更多的其余对象去侦听这个model。这样的话,若是model发生了某种改变就能够经过事件来发出通知。

可是,大量的将Backbone.Events扩展到实际的对象上,显然是一种内存浪费,那么何不将它扩展到原型prototype上呢?因而就有了Backbone的Model和View等核心类。例如Backbone.Model

var Events = Backbone.Events = { .. }

var Model = Backbone.Model = function(attributes, options) {
    ...
};

_.extend(Model.prototype, Events, { ... })

从上面的代码能够看出,Backbone核心的类只不过是将Backbone.Events扩展到自身的prototype上罢了,这样全部基于Backbone核心类建立出来的对象就有了事件能力。

下面是一个体现观察者模式的经典例子:

var Todo = Backbone.Model.extend({
    model.trigger('destroy');
});

var TodoView = Backbone.View.extend({

    events: {
      "click a.destroy" : "clear",
    },

    initialize: function() {
      this.listenTo(this.model, 'destroy', this.remove);
    },

    clear: function() {
      this.model.destroy();
    },

    remove: function() {
      this.$el.remove();
    }

});

上面的例子忽略了不少细枝末节,只是想说明一个界面元素的删除动做,首先是删除模型,模型随后触发删除事件,因为这个删除事件,界面元素才被删除

探究Backbone事件的实现原理

被侦听的对象维护一个事件数组_event,其余对象在调用listenTo时,会将事件名与回调维护到队列中:

一个事件名能够对应多个回调,对于被侦听者而言,只知道回调的存在,并不知道具体是哪一个对象在侦听它。

当被侦听者调用trigger(name)时,会遍历_event,选择同名的事件,并将其下面全部的回调都执行一遍。

总结

Backbone虽然是MVC模式的框架,可是其核心倒是UI界面的观察者模式和事件机制。有了事件,并灵活运用观察者模式,才能实现复杂界面的复杂逻辑。本文对此进行了阐述,若有不妥之处,请指正。

相关文章
相关标签/搜索