我已经看到了这个问题的解决方案,但似乎无法再找到它......
//
// A simple implementation of the subscriber pattern
//
var Subject = function()
{
this._observers = [];
};
// Here lies the problem
Subject.prototype.attach = function(observer, func)
{
this._observers.push(observer);
this._observers.push(func);
};
// And this only makes the problem worse
Subject.prototype.notify = function(pData)
{
var len = this._observers.length;
for(var i = 0; i < len; i += 2)
this._observers[i][this._observers[i + 1]](pData, this._observers[i]);
};
// Store the data related to the generic Observer
var Observer = function(pId){
this._el = pId;
};
//
// Notify and Update represent two possible functions that do different stuff
//
Observer.prototype.notify = function(pData, pThis)
{
document.getElementById(pThis._el).textContent = 'Notify: ' + pData;
};
Observer.prototype.update = function(pData, pThis)
{
document.getElementById(pThis._el).textContent = 'Update: ' + pData;
};
// In action
var server = new Subject();
var client1 = new Observer('observer_1' /* the ID to some DOM element */);
var client2 = new Observer('observer_2');
// Another manifestation of the problem I've ran into
server.attach(client1, 'notify');
server.attach(client2, 'update');
server.notify('[some data]');
我的问题: 当Subject调用它已注册的所有观察者时,被调用的回调在Subject的上下文中执行。换句话说,何时
Observer.update
调用,因为它是从Subject内部调用的,是对
的引用this._el
指的是不存在的Subject._el。我的解决方法是在我的主题中注册2件事:对Observer的引用,以及在Observer中具有回调名称的字符串。然后,当Subject广播通知时,它会调用已注册的回调并向Observer发送对Observer的引用,该引用将被用作:
// instead of this._el (which would refers to server._el,
// do <observer_1>._el
我希望我已经清楚地表达了我的问题,以便得到我需要的帮助。
谢谢!
答案 0 :(得分:1)
它的要点是范围。设置回调函数时,必须确保它在观察者的上下文中执行:
// Here lies the problem
Subject.prototype.attach = function(observer, func)
{
this._observers.push(observer);
this._observers.push(_.bind(func, observer));
};
最简单的方法是使用underscore.js并更改绑定。您也可以使用call()和apply()创建自己的。
这可能更接近您所寻找的内容:http://jsfiddle.net/UQ3Ay/2/