我正在深入研究这两个很棒的作品的源代码,然而,我无法弄清楚它们的实现,模型的数据如何立即更新视图的时刻如何变化,
在第一次开始时,我认为它可能在Gecko中使用类似object.watch()
的东西,显然我无法在两个来源中找到它们
任何关于他们核心思想的想法
提前谢谢〜
答案 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)
您的视图需要监听其模型,并触发模型的更改事件。
this.model.bind('change', this.render, this);
我为你创建了一个jsFiddle,看看它是如何工作的:http://jsfiddle.net/Atinux/Jb2rd/
我真的不知道Knockout JS,但我不认为这是一样的,如果我找到答案,我会更新我的帖子。