【发布时间】:2019-12-10 14:05:03
【问题描述】:
我的 HTML 页面上有以下控制器:
...
<div data-controller="parent">
<div data-target="parent.myDiv">
<div data-controller="child">
<span data-target="child.mySpan"></span>
</div>
</div>
</div>
...
此子控制器映射到以下child_controller.js 类:
export default class {
static targets = ["mySpan"];
connect() {
document.addEventListener("myEvent", (event) => this.handleMyEvent(event));
}
handleMyEvent(event) {
console.log(event);
this.mySpanTarget; // Manipulate the span. No problem.
}
}
如您所见,Stimulus 控制器的connect() 上有一个事件监听器,当它检测到事件被触发时,它会记录该事件并操作 span 目标。
当我从我的parent_controller.js 替换目标myDiv 的内容时出现问题:
...
let childControllerHTML = "<div data-controller="child">...</div>"
myDivTarget.innerHTML= childControllerHTML;
...
现在myEvent 已启动,事件侦听器不会选择一次,而是两次(因为相同的事件被记录了两次)。每次后续替换子 HTML 时,事件都会比以前多记录一次。
我知道可以利用document.removeEventListener 来防止旧控制器仍然监听事件:
export default class {
static targets = ["mySpan"];
connect() {
this.myEventListener = document.addEventListener("myEvent", (event) => this.handleMyEvent(event));
}
disconnect() {
document.removeEventListener("myEvent", this.myEventListener);
}
handleMyEvent(event) {
console.log(event);
this.mySpanTarget; // FAILS. Can't find span.
}
}
但是这样做会使handleMyEvent 方法丢失context,因为它不再在this 下找到mySpanTarget。
如何从我已经无法访问的子控制器中删除侦听器,因为它不再在 DOM 中,同时保留上下文?
【问题讨论】:
标签: javascript event-listener stimulusjs