Javascript объем этого в шаблоне подписчика - PullRequest
0 голосов
/ 22 марта 2012

Я видел решение этой проблемы некоторое время назад, но, похоже, не могу найти его снова ...

//
// 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

Надеюсь, я четко изложил свой вопрос, чтобы получить необходимую помощь.

Спасибо!

1 Ответ

1 голос
/ 22 марта 2012

http://jsfiddle.net/UQ3Ay/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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...