刺激控制器:事件被监听多次;如何删除事件监听器并保留上下文?

问题描述 投票:0回答:1

我的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()上有一个事件侦听器,当它检测到事件被触发时,它将记录该事件并操纵跨度目标。

当我从myDiv替换目标parent_controller.js的内容时出现问题:

...
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,因为它不再在mySpanTarget下找到this

如何在保留上下文的情况下,从不再具有访问权限的子控制器中删除侦听器,因为它不再在DOM中?

javascript event-listener stimulusjs
1个回答
0
投票
© www.soinside.com 2019 - 2024. All rights reserved.