【问题标题】:Events emitted from slotted components从开槽组件发出的事件
【发布时间】:2020-05-22 21:45:42
【问题描述】:

我尝试将应用程序包装到“存储库”组件中,并且该外部组件应处理与后端的所有通信,例如加载、更新、删除可编辑数据。我以为我可以将事件发送到 Repository 组件,但我没有按照我的方式工作。有没有人发现问题或可以解释,为什么这不起作用以及如何正确处理事件?我可以改用可写对象,但事件会使它更具可读性。这是一个简化的示例和一个纤细的 REPL 链接:

https://svelte.dev/repl/e1eae56c7d5e48b2a99299f1bc1bf970?version=3.22.3

App.svelte:

<script>
    import Repository from './Repository.svelte'
    import Application from './Application.svelte'
</script>

<Repository>
    <Application on:save={() => console.log('caught in App')} />
</Repository>

Repository.svelte:

<div on:save={() => console.log('caught in Repository')}>
    <slot></slot>
</div>

Application.svelte:

<script>
    import {createEventDispatcher} from 'svelte'

    const dispatch = createEventDispatcher();

    function saveHandler() {
        console.log('dispatching')
        dispatch('save')
    }

</script>

<button on:click={saveHandler}>
    Save
</button>

期望的输出是

dispatching
caught in Repository

但它只打印

dispatching
caught in App

当按钮被点击时。

【问题讨论】:

  • 如果&lt;Application&gt; 始终是&lt;Repository&gt; 的后代,那么这可能是context API 的一个很好的用例——它允许两个组件相互通信,而无需应用程序开发人员需要手动将它们与事件处理程序等联系起来。
  • 是的。存储库可以使用所有存储库方法 (CRUD) 创建上下文,并且我可以停止发送和转换所有这些自定义事件。从未使用过它,但它看起来会以一种非常优雅的方式解决我的问题。
  • 听起来你在找event forwarding
  • @JustinMakeig 这就是我已经使用的。但它开始变得非常丑陋。我发现自己通过许多层转发事件,甚至编写处理程序只是为了用不同的事件名称调度相同的值。

标签: svelte


【解决方案1】:

找到了至少一种解决方案,let 指令可以提供帮助,尽管它不是纯粹的事件并且相当冗长。

https://svelte.dev/repl/a03214d522cd4bcba67f86c426a3b28d?version=3.22.3

App.svelte:

<script>
    import Repository from './Repository.svelte'
    import Application from './Application.svelte'
</script>

<Repository let:saveHandler={saveHandler}>
    <Application on:save={saveHandler} />
</Repository>

Repository.svelte:

<script>
    function saveHandler() {
        console.log('caught in Repository')
    }
</script>

<div>
    <slot {saveHandler}></slot>
</div>

Application.svelte:

<script>
    import {createEventDispatcher} from 'svelte'

    const dispatch = createEventDispatcher();

    function saveHandler() {
        console.log('dispatching')
        dispatch('save')
    }

</script>

<button on:click={saveHandler}>
    Save
</button>

缺点(或优点)是我们必须在主组件上使用 let 指令公开存储库中的所有方法,并捕获那里的事件,这可能是很多不需要的事件转发(因为事件只会冒泡上一级)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-14
    • 2021-07-11
    • 2018-06-06
    • 2018-12-29
    • 2021-02-12
    • 2021-07-26
    • 2017-01-01
    • 2018-05-11
    相关资源
    最近更新 更多