我想在我的项目中使用Tabulator,该项目尚未与Svelte集成。这是我之前已经使用过的非常完整的数据表库。但是,当我尝试使用操作按钮(编辑,删除...)创建典型列时,我一直使用它们的Custom Formatters作为字符串返回html。
格式化列的函数返回如下所示:
return '<ul class="actions_row"><li><custom-button on:click={handleClick}>Edit</custom-button></li></ul>';
<custom-button />
是使用<svelte:options>
创建的自定义元素,并通过index.html(<script src="lib/CustomButton.js"></script>
)添加到项目中。
自定义按钮显示在表中,但是它无法转发事件。似乎该组件无法在其自身范围之外进行通信。
您的自定义格式化程序返回的字符串将被处理为“普通” HTML,因此Svelte语法不再可用...即on:click
是Svelte语法,将不会被浏览器处理。
我不是自定义元素专家,但是很遗憾,according to others,您试图做的事是不可能的。也就是说,您不能仅通过HTML在自定义元素上注册自定义事件侦听器。您可能必须从JS执行此操作。像这样的东西:
<script>
document.querySelector('custom-button')
.addEventListener('my-event', e => {
console.log(e.detail)
})
</script>
此外,请注意,Svelte中来自自定义元素的事件当前受到某些限制(请参阅this issue。
因此,为了让自定义元素具有自定义事件,您必须使用某种解决方法。例如,这是一个可以触发上述片段中的侦听器的组件:
<svelte:options tag="custom-button" />
<script>
import { onMount } from 'svelte';
let el
onMount(() => {
const interval = setInterval(() => {
let event = new CustomEvent('my-event', {
detail: {time: Date.now()},
bubbles: true,
composed: true, // needed for the event to traverse beyond shadow dom
})
el.dispatchEvent(event)
}, 1000)
return () => {
clearInterval(interval)
}
})
</script>
<button bind:this={el}><slot /></button>
请注意,此类代码对旧版浏览器的支持有限。
话虽如此,就您的示例而言,恰恰是这样,您显然可以通过在本机浏览器onclick
而非Svelte的on:click
中注册事件来使其正常工作。我仍然不是CE专家,但我的猜测是浏览器还会处理所有本机元素(例如,单击或按下CE元素)上可用的标准事件...
所以,看来这应该对您有用:
return '<ul class="actions_row"><li><custom-button onclick="handleClick">Edit</custom-button></li></ul>';
注意:onclick="handleClick"
而不是on:click={handleClick}
。您现在位于标准浏览器领域,因此适用常规规则,就如同使用普通<button>
... handleClick
必须在范围内可用一样,等等。