2009-11-26 18 views
7

Mam obiekt flash innej firmy, który mogę manipulować za pośrednictwem udostępnionego przez niego interfejsu JavaScript javascript. Próbuję wysłuchać wydarzenia na tym obiekcie, a następnie ogniskuję obiekt wewnątrz obiektu, aby jeszcze bardziej spopularyzować to wydarzenie. Zdarza się, że używam EXT Js, ale nie sądzę, że jest to ważne.addEventListener i zakres tego

Przykładowy kod

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

Moim problemem jest to, że „to” wewnątrz funkcji anonimowej odnosi się do obiektu, który opalane zdarzenie zamiast mojego obiektu, który chcę ognia zdarzenie dalej.

Jest to kolejny problem z zakresu. Z góry dziękuję za pomoc.

Odpowiedz

0

Jest to typowe podejście do tego problemu: -

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

Wolę 'var self = this;'. Utworzenie funkcji, a następnie jej wykonanie podczas przekazywania "this" jako parametru, wydaje się nieco przesadzone - kod jest nieco dłuższy ;-) –

+0

@Andy: Tak, często robię to również, gdy kod istnieje w małym kontekście wykonania. Jednak powyższe jest standardowym podejściem, które działa w większej liczbie różnych scenariuszy.Zakres identyfikatora "self" ogranicza się tylko do zamknięcia, nie ma niebezpieczeństwa, że ​​kolejny kod może zmodyfikować wartość zawartą w nim przed wywołaniem zdarzenia. Nie dotyczy to podejścia 'var self = this;'. – AnthonyWJones

12

A co z tworzeniem zmiennej zewnętrznej przed odniesieniem do "tego" obiektu. Na przykład:

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

Tak, to jest normalny idiom. Zmienna zamknięcia jest często nazywana "tym" lub "self" (chociaż nie sądzę, że ten ostatni jest świetnym pomysłem, ponieważ 'self' ma ustalone - choć bezużyteczne - istniejące znaczenie w JavaScript). – bobince

+0

OK, który działa. W interesie jest inny sposób niż ustawienie zmiennej. Na przykład za pomocą zamknięcia? – Jonnio

+1

@bobince: Preferuję 'self'. 'self' jest ujawniane przez' window' jako odnośnik do niego samego. Cieszę się, że mogę ponownie użyć identyfikatora w innych zakresach. Wydaje mi się, że mam właściwe znaczenie i nie koliduję z tym, że oznacza to, że "ja" także jest oknem. – AnthonyWJones

5

Podczas gdy inne odpowiedzi osiągnąć to, co potrzebne, one nie działają w najbardziej efektywny sposób (Scalable) , ponieważ nie oddzielają ostatecznie obiektu widoku (this.chart) od logiki tego widoku (fireEvent()). W aplikacjach MVC te "decyzje" dotyczące widoku znajdują się w kontrolerze . Kontroler "steruje" widokami i powinien zawierać wszystkie interfejsy API, do których może uzyskać dostęp widok.

W twoim przykładzie, this jest kontrolerem i to dobrze (to znaczy, że dodajesz swoich słuchaczy we właściwym miejscu). Wszystko, co naprawdę trzeba zrobić, to wiążą obsługi do zakresu rzeczy, które należy zrobić z „obsługa” - w przypadku: this:

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

Jakie inne odpowiedzi na tej stronie zrobili jest to więc widok staje się jego własnym kontrolerem, ale tylko podczas obsługi zdarzeń "tworzenia" poprzez przypisanie tymczasowego odwołania do "kontrolera" przy użyciu var self = this. Znowu działa to dobrze, ale nie działa dobrze na dużą skalę w aplikacjach sterowanych zdarzeniami i nie ma większego sensu, jeśli masz do czynienia z wieloma zdarzeniami.

.bind() jest implementacją ECMAScript 5. Jeśli jest to potrzebne do pracy w jeszcze starszych przeglądarkach, dobrze jest to opisać tutaj (używając functions i): https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

+0

W niektórych implementacjach MVC (jak w przykładzie opisanym tutaj: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller), sam program obsługi (np. Twój '.fireEvent () ') jest zdefiniowany w widoku, ale kontroler wywołuje go w razie potrzeby. Mogłoby to pozwolić na to, że w ogóle nie użyjesz '.bind()' lub samo-odniesienia, ale sprawi to, że twój przewodnik będzie bardzo małomienny; a twoja aplikacja będzie bardzo duża. – Benny