2015-05-25 6 views
23

W tym scenariuszu ES6, zdarzenie click zrobić prace bo sayHello funkcja jest wywoływana z this.elm (<div>) jako this.ES6 Klasa: nie Dostęp do „to” z „” addEventListener stosowanej na metodzie

jak powiązać wydarzenie z metodą bez utraty zakresu?

class player{ 
    constructor(name){ 
    this.name = name; 
    this.elm = document.createElement('div'); 
    this.elm.addEventListener('click', this.sayHello); 
    } 
    sayHello(){ 
    console.log(this.name + ' say: "hello!"'); // 'undefined say 'hello!"'; 
    } 
    kill(){ 
    console.log(`RIP ${this.name} :'(`); 
    this.elm.addClass('dead'); 
    this.elm.removeEventListener('click', this.sayHello); 
    } 
} 

Odpowiedz

63

Jest to ogólny JS problem, ale istotą jest to, że

this.elm.addEventListener('click', this.sayHello); 

nie jest inaczej niż

var fn = this.sayHello; 
this.elm.addEventListener('click', fn); 

są przechodzącą funkcję jako obsługi zdarzeń, ale nie zapewniłem, że gdy fn zostanie wywołany, że this zostanie ustawiony na pożądaną wartość. Najprostszym sposobem, aby to zrobić w ES5 byłoby

this.elm.addEventListener('click', this.sayHello.bind(this)); 

lub w ES6, wykorzystując funkcję strzałka:

this.elm.addEventListener('click', evt => this.sayHello(evt)); 

Należy jednak pamiętać, że oba te rozwiązania złamie (już lekko uszkodzony) logiki kill ponieważ

this.elm.removeEventListener('click', /* what? */); 

nie ma żadnego odniesienia do funkcji, którą załączonym już, więc nie masz możliwości usunięcia obsługi zdarzeń.

którą proponujemy dwie opcje:

// Create a new function that is bound, and give it a new name 
// so that the 'this.sayHello()' call still works. 
this.boundSayHello = evt => this.sayHello(evt); 
this.elm.addEventListener('click', this.boundSayHello); 
this.elm.removeEventListener('click', this.boundSayHello); 

lub

// Bind the function with the same name and use `.bind` instead of the 
// arrow function option. 
this.sayHello = this.sayHello.bind(this); 
this.elm.addEventListener('click', this.sayHello); 
this.elm.removeEventListener('click', this.sayHello); 
+0

podziękować to co używam, ale każdy obiekt musi mieć obiekt wskazując na każdym zbindowanych funkcji potrzebnych jako callback http: //codepen.io/yukulele/pen/yNVVxV/?editors=001 –

Powiązane problemy