2009-11-26 7 views
7

У меня есть сторонний Flash-объект, который я могу манипулировать с помощью предоставленного им javascript-интерфейса. Я пытаюсь прослушать событие на этом объекте, а затем запустить событие внутри моего объекта, чтобы еще больше разжечь событие. Я, случается, использую EXT Js, но я не думаю, что это важно здесь.addEventListener и область действия этого

Пример кода

this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}, false) 

Моя проблема заключается в том, что «это» внутри анонимной функции относится к объекту, который уволил событие, а не мой объект, который я хочу стрелять событие на.

Его еще одна проблема с объемом. Заранее благодарю за любую помощь.

ответ

0

Это типичный подход к этой проблеме: -

(function(self) { 
    self.chart.addEventListener('create', function() {self.fireEvent('created');}, false); 
})(this); 
+2

Я предпочитаю 'var self = this;'. Создание функции, а затем ее выполнение при передаче 'this', поскольку параметр кажется немного завышенным - код немного длиннее ;-) –

+0

@ Andy: Да, я часто это делаю, когда код существует в небольшом контексте выполнения. Однако приведенный выше стандарт является стандартным подходом, который работает в более широком спектре сценариев.Объем идентификатора 'self' ограничен только закрытием, нет опасности, что последующий код может изменить значение, содержащееся в нем до возникновения события. Это не относится к подходу «var self = this;». – AnthonyWJones

12

Как создать внешнюю переменную перед ссылкой на этот объект. Например:

var _this = this; 
this.chart.addEventListener('create', function() { _this.fireEvent('created'); }, false) 
+4

Да, это нормальная идиома. Замыкающая переменная часто называется 'that' или' self' (хотя я не думаю, что последняя отличная идея, поскольку «self» имеет установленное, хотя и бесполезное, существующее значение в JavaScript). – bobince

+0

Хорошо, что работает. Из интереса существует другой способ, кроме установки переменной. Например, используя закрытие? – Jonnio

+1

@bobince: Я предпочитаю «себя». 'self' раскрывается' window' ссылкой на себя. Я очень рад повторить использование идентификатора в других областях. Мне кажется, что я ношу правильное значение и не сталкиваюсь с тем, что это означает, что «само» оказывается оконным. – AnthonyWJones

5

В то время как другие ответы выполнить то, что вам нужно, они не работают наиболее эффективно (масштабируемый) способ , потому что они не в конечном итоге отделяют объект вида (this.chart) от логики этого представления (fireEvent()). В приложениях MVC эти представления «решения» находятся в контроллере . Контроллер «управляет» просмотрами и должен содержать все API, к которым может обратиться представление.

В вашем примере this является контроллером, и все в порядке (это означает, что вы добавляете слушателей в нужное место). Все, что вам действительно нужно сделать, это связать обработчик рамки вещи, которые должны делать «обработки» - в вашем случае: this:

// `this` is the controller of `chart` 
this.chart.addEventListener('create', function() { 
    this.fireEvent('created'); 
}.bind(this)); 

Что другие ответы на этой странице, сделали это сделали его поэтому ваше представление становится его собственным контроллером, но только при обработке событий «создавать», назначая временную ссылку на «контроллер», используя var self = this. Опять же, это работает отлично, но это не очень хорошо работает в масштабах приложений, управляемых событиями, и это не имеет никакого смысла, если у вас есть много событий для обработки.

.bind() - это реализация ECMAScript 5. Если это необходимо для работы в более старых браузерах, здесь описывается хороший способ его использования (с использованием functions и .call()): https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

+0

В некоторых реализациях MVC (как в примере, описанном здесь: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), сам обработчик (например, ваш '.fireEvent () ') определяется в представлении, но контроллер вызывает его по мере необходимости. Это может позволить вам не использовать '.bind()' или самостоятельную ссылку вообще, но сделает ваш обработчик очень немодульным; и ваше приложение будет расти очень большим. – Benny