2017-07-07 59 views
5

我正在嘗試爲當前項目上的交互式日曆編寫ES6類。ES6類 - 從事件處理程序中調用方法

的Class看起來類似於下面:

class Calendar { 

constructor (s) { 

    this.eventButtons = s.eventButtons; 
    this.eventButtons.forEach(button => button.addEventListener('click', this.method1); 
    this.eventBoxes = s.eventBoxes; 


method1 (e) { 
    e.preventDefault(); 
    this.method2(e.target.href); 
} 

method2 (url) { 
    console.log(url); 
} 

} 


export default Calendar; 

我知道,「這個」關鍵字的上下文從構造改爲已被點擊方法1函數內的按鈕。但是我不知道如何保持按鈕和構造函數的上下文在同一個函數中。我嘗試將按鈕事件監聽器代碼更改爲以下代碼:

this.eventButtons.forEach(button => button.addEventListener('click', this.method1).bind(this); 

但是,這只是將「this」關鍵字的上下文切換到構造函數而不是按鈕。我需要在我的功能中使用兩者。

任何想法?我希望這是一個很常見的問題?

+0

的[無法調用它在ES6在Node.js的限定它的一類內的方法](可能的複製https://stackoverflow.com/questions/39621821/cannot-call-a-method-within- a-class-it-defined-it-in-es6-in-node-js) – noahnu

回答

5

由於您使用的是ES6,您是否嘗試過使用arrow function

箭頭函數表達式具有比功能 表達較短的語法和不結合其自身的此,自變量,超級或 new.target。這些函數表達式最適合非方法 函數,並且它們不能用作構造函數。

method1 = (e) => { 
    e.preventDefault(); 
    this.method2(e.target.href); 
} 
+0

雖然這不是ES6。它是[class-fields](https://github.com/tc39/proposal-class-fields)第2階段提案 – CodingIntrigue

1

嘗試使用lambda表達式來設置你的事件的委託爲好。像下面這樣:

button.addEventListener('click', (e) => { e.preventDefault(); this.method2(); }); 
6

你可以創建一個閉包來發送事件和按鈕。閉合將保持這一背景下,併發送按鈕以及

button => button.addEventListener('click', event => this.method1(event, button)) 
2

您可以使用bind使局部功能:

this.eventButtons.forEach(button => button.addEventListener('click', this.method1.bind(this, button)); 

它的工作原理假設你改變method1是:

method1 (button, e) { 
    e.preventDefault(); 
    this.method2(e.target.href); 
} 
+0

你缺少右括號。你的意思是綁定到什麼地方? – noahnu

+0

謝謝,修正了它 – amiramw

3

您有幾個選擇:

您可以將方法Š自己:

this.method1 = this.method1.bind(this); 
this.method2 = this.method2.bind(this); 

那裏,如果你正在使用Babel(或其他一些transpiler)是的bind operator。它尚未被納入標準,所以我會厭倦使用它。使用綁定運算符,您可以執行以下等效操作:

this.method1 = ::this.method1 
this.method2 = ::this.method2 

另一個選項是完成已經完成的工作,只是已更正。

您必須綁定該方法,而不是forEach的結果。

this.eventButtons.forEach(button => 
    button.addEventListener('click', this.method1.bind(this))); 

或綁定OP:

this.eventButtons.forEach(button => 
    button.addEventListener('click', ::this.method1)); 

最後,您還可以使用箭頭符號的詞彙範圍,建立一個包裝功能的選項:

this.eventButtons.forEach(button => 
    button.addEventListener('click', (...params) => this.method1(...params))); 
+0

我剛試過你的建議:this.eventButtons.forEach(button => button.addEventListener('click',this.method1.bind(this)));這使得'this'關鍵字的上下文成爲構造函數。這很棒。但是,我如何參考按鈕? –

+1

@JamesHowell'e.currentTarget'或'e.target' - 與你已經有的相同 – CodingIntrigue

+1

@noahnu綁定語法'::'仍然是階段0 - 不是ES7 – CodingIntrigue

2

如果你使用ES6 ,你也可以用for代替forEach。這可以防止用自己的範圍創建另一個回調。在此代碼中,關鍵字「this」仍指原始類。

this.eventButtons = s.eventButtons; 
for(b of this.eventButtons){ 
    b.addEventListener('click',() => this.method1); 
} 
相關問題