Я видел решение этой проблемы некоторое время назад, но, похоже, не могу найти его снова ...
//
// 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]');
Моя проблема:
Когда Субъект вызывает всех наблюдателей, которые он зарегистрировал, обратный вызов, который вызывается, выполняется в контексте Субъекта. Другими словами, когда
Observer.update
вызывается, поскольку он был вызван из субъекта, ссылка на
this._el
относится к Subject._el, который не существует. Мой обходной путь - зарегистрировать 2 вещи в моем предмете: ссылку на наблюдателя и строку с именем обратного вызова внутри этого наблюдателя. Затем, когда Субъект передает уведомление, он вызывает зарегистрированный обратный вызов и отправляет Обозревателю ссылку на Обозревателя, которая используется как это:
// instead of this._el (which would refers to server._el,
// do <observer_1>._el
Надеюсь, я четко изложил свой вопрос, чтобы получить необходимую помощь.
Спасибо!