当模型更新时,骨干和淘汰怎么会改变观点?

时间:2012-01-05 07:36:42

标签: javascript backbone.js knockout.js

我正在深入研究这两个很棒的作品的源代码,然而,我无法弄清楚它们的实现,模型的数据如何立即更新视图的时刻如何变化,
在第一次开始时,我认为它可能在Gecko中使用类似object.watch()的东西,显然我无法在两个来源中找到它们 任何关于他们核心思想的想法 提前谢谢〜

3 个答案:

答案 0 :(得分:1)

让我们来看看主干事件的实现:

调用绑定,您可以在散列_callbacks中的传递密钥(ev)下存储传递的函数(回调)。

Backbone.Events = {

    // Bind an event, specified by a string name, `ev`, to a `callback` function.
    // Passing `"all"` will bind the callback to all events fired.
    bind : function(ev, callback, context) {

      //create a new hash to save the callbacks when it doesn't exits yet
      var calls = this._callbacks || (this._callbacks = {});

      //create a new array to store the callbacks if its doesn't exits yet
      var list  = calls[ev] || (calls[ev] = []);

      //add a new array holding the function and the context with which the function 
      // will be called later
      list.push([callback, context]);

      return this;
    },

取消绑定只是从散列中删除所有或传递的回调。

    // Remove one or many callbacks. If `callback` is null, removes all
    // callbacks for the event. If `ev` is null, removes all bound callbacks
    // for all events.
    unbind : function(ev, callback) {
      var calls;
      if (!ev) {
        this._callbacks = {};
      } else if (calls = this._callbacks) {
        if (!callback) {
          calls[ev] = [];
        } else {
          var list = calls[ev];
          if (!list) return this;
          for (var i = 0, l = list.length; i < l; i++) {
            if (list[i] && callback === list[i][0]) {
              list[i] = null;
              break;
            }
          }
        }
      }
      return this;
    },

触发器将调用存储在传递键下的所有函数。

    // Trigger an event, firing all bound callbacks. Callbacks are passed the
    // same arguments as `trigger` is, apart from the event name.
    // Listening for `"all"` passes the true event name as the first argument.
    trigger : function(eventName) {
      var list, calls, ev, callback, args;
      var both = 2;
      if (!(calls = this._callbacks)) return this;
      while (both--) {
        ev = both ? eventName : 'all';
        if (list = calls[ev]) {
          for (var i = 0, l = list.length; i < l; i++) {
            if (!(callback = list[i])) {
              list.splice(i, 1); i--; l--;
            } else {
              //when more then one argument was passed to the trigger function
              // this arguments will be passed to call of the stored function
              args = both ? Array.prototype.slice.call(arguments, 1) : arguments;

              //here the stored function is called with the optional passed context
              callback[0].apply(callback[1] || this, args);
            }
          }
        }
      }
      return this;
    }

  };

这是JavaScript的优势之一,您可以将函数的全部范围存储在变量中,稍后再调用它们。所以添加结束在数据绑定中没有魔力。它只是一个数据结构,用于在哈希中使用密钥保存函数并使用密钥调用它们。

由于Backbone对象View,Model,Controller扩展了Events对象,您可以在所有对象上绑定/触发事件。因此,当视图绑定模型更改的函数时,模型会在添加,删除等内容时调用this.trigger('change')

答案 1 :(得分:0)

我不熟悉Knockout,但Backbone会在数据更改时手动触发事件。来自Model#set

if (!alreadyChanging && !options.silent && this._changed) this.change(options);

这是来自Model#change

change : function(options) {
  this.trigger('change', this, options);
  this._previousAttributes = _.clone(this.attributes);
  this._changed = false;
},

视图可以收听change事件并相应地更新。

答案 2 :(得分:0)

Backbone.js的

您的视图需要监听其模型,并触发模型的更改事件。

this.model.bind('change', this.render, this);

我为你创建了一个jsFiddle,看看它是如何工作的:http://jsfiddle.net/Atinux/Jb2rd/

我真的不知道Knockout JS,但我不认为这是一样的,如果我找到答案,我会更新我的帖子。