2017-10-04 291 views
7

總之:我想.bind的結果綁定在它自己的呼叫刪除的事件處理程序

var bound = foo.bind(this,bound); 

的arguement,因爲我不知道怎麼回事,解決我的問題。

問題:

我有依賴其他項目的陣列上的項目。 一旦這些項目之一被刪除,我想刪除依賴項,並刪除所有依賴關係上放置的偵聽器。

我努力去除其他依賴項的事件處理程序。我試圖使用綁定,但由於處理函數是刪除監聽器的函數,我發現我必須將自己的調用中的bind()調用的結果作爲參數進行綁定。這當然不起作用。

綁定調用bellow將未綁定的'handler'版本作爲參數綁定,因此removeEventListener不起作用,因爲它是該函數的不同副本。

問題是:我可以使用綁定來做到這一點和/或我該如何解決這個問題?

即時通訊使用eventemitter3,但它應該是任何事件庫相同。

setHandlers(dependentItem,dependencies) 
{ 
    var handler = this.onDependencyRemoved; 
    handler = handler.bind(this,dependentItem,dependencies,handler);//bind itself as third argument 
    dependencies.forEach(dependency => { 
     dependency.addEventListener("removed",handler); 
    }); 
} 
onDependencyRemoved(dependentItem,dependencies,handler) 
{ 
    dependentItem.remove(); 
    dependencies.forEach(dependency => { 
      dependency.removeEventListener("removed",handler); 
    }); 
} 

編輯:

完整的工作示例中的NodeJS運行:

const EventEmitter = require('events'); 
//const EventEmitter = require('eventemitter3'); 

class MyEmitter extends EventEmitter { 
    remove() { 
     console.log("I'm being removed, this should happen only once"); 
    } 
} 
var dependent = new MyEmitter(); 
var dependencies = [new MyEmitter(),new MyEmitter()]; 

var handler = (e) => removeHandler(dependencies,dependent,handler); 

dependencies.forEach(dependency => dependency.once('removed',handler)); 

var removeHandler = function(dependencies,dependent,handler) { 
    //remove the dependent object because one of the dependencies was removed 
    dependent.remove(); 
    //remove the listeners from all of the dependencies 
    dependencies.forEach(dependency => { 
     console.log('before removing: '+dependency.listeners('removed').length); 
     dependency.removeListener('removed',handler); 
     console.log('after removing: '+dependency.listeners('removed').length); 
    }); 
} 

//should remove the dependent object 
dependencies[0].emit("removed"); 
//should not do anything anymore since the listeners are removed 
dependencies[1].emit("removed"); 
+0

使用[事件委託](https://stackoverflow.com/a/1688293/402037)並在父元素上添加_one_處理程序。 – Andreas

+0

@Andreas我在node.js.這些項目是模型/ ES6類實例,而不是DOM項目。 – Flion

回答

7

你不能做到這一點使用bind,但你可以通過使用封閉做到這一點比較容易 - 無論是直接爲要綁定的函數,或者在您自己的輔助函數中,類似於bind。這是簡單的

const handler = (e) => this.onDependencyRemoved(dependentItem, dependencies, handler, e); 

我不知道爲什麼這兩個函數是任何東西的方法;他們看起來相當靜態。它可能可能使他們的方法dependentItem有意義,在這種情況下,參數甚至整個handler不需要存儲在閉包變量中,但可以使實例屬性在構造函數中初始化。

+0

與關閉它仍然無法正常工作。當我刪除事件監聽器時,一旦註冊的處理器與'onDependencyRemoved'使用的處理器不匹配('===')。我用閉包設置編輯了這個問題。 – Flion

+0

@Flion我無法複製,您的代碼應該可以工作。我相信你要麼沒有顯示完整的實際代碼,要麼問題在別處。你可以做[mcve]嗎?我也很好奇你如何通過addEventListener *保存'==='「*處理函數,因爲'addEventListener'沒有提供它的存儲 – Bergi

+1

是的我只是做了一個最小的完整例子,它工作使用node.js本地EventEmitter和'eventEmitter3'庫都很好。我意識到並不是所有的時間removeEventListener被調用它刪除的東西,因爲發射'刪除'事件的項目已經刪除了它自己,因爲我使用'一次'。 Tnx的幫助!明天我會給予獎勵。這對我來說是一個重要的問題,我從來不知道一個簡單的閉包可以像你展示的那樣在它自己的函數中重用一個值。 – Flion

6

有更好的方法可以解決別人提到的問題。然而,有一個與代碼更根本的問題:

var bound = foo.bind(this,bound); 

bound在代碼中的值,在執行的時候,是undefined。這相當於只調用foo.bind(this),這可能不是您想要的。

+0

我意識到這一點,我只寫它試圖解釋我正在嘗試做什麼。 – Flion