2017-10-04 289 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