【问题标题】:Can you modify a result obtained via #await?您可以修改通过#await 获得的结果吗?
【发布时间】:2021-01-10 00:21:59
【问题描述】:

问题

我正在尝试在 Svelte 中利用 {#await},但似乎无法找到一种方法使其结果具有响应性 ({:then result})。

示例

如果您想亲自尝试,可以找到此示例in the REPL

在这个应用程序中:

  1. 你通过{#await}从服务器加载了一些todos
  2. 您使用 {#each} 块对其进行迭代,并在单击时切换其 done 属性。
  3. 如何更新todos

App.svelte

<script>
    import Todo from "./Todo.svelte";
    
    const todos = [{
        title: 'Todo 1',
        done: false
    }, {
        title: 'Todo 2',
        done: false
    }];
    
    const getTodos = new Promise((res, rej) => setTimeout(res.bind(null,todos), 1000));
    
    const updateTodos = ({detail: change}) => {
        // ¿How can I update todos?
        console.log(change);
    }
</script>

{#await getTodos}
    Loading..
{:then todos}
    {#each todos as todo}
        <Todo {todo} on:change={updateTodos}></Todo>    
    {/each}
    <pre>{JSON.stringify(todos,null,2)}</pre>
{:catch error}
    {error}
{/await}

Todo.svelte

<script>
    export let todo = null;
    
    import { createEventDispatcher } from "svelte";

    const dispatch = createEventDispatcher();
    
    const toggle = () => {
        todo = {...todo,done:!todo.done};
        dispatch("change",todo);
    };
</script>

{#if todo}
    <li on:click={toggle}>
        {todo.title}
        ({todo.done})
    </li>
{/if}

最后的话

我只对利用{#await}的解决方案感兴趣,我可以用其他模式解决这个问题。

【问题讨论】:

    标签: svelte


    【解决方案1】:
    <Todo bind:todo={todo} />
    

    在上下文中:

    App.svelte

    <script>
        import Todo from "./Todo.svelte";
        
        const todos = [{
            title: 'Todo 1',
            done: false
        }, {
            title: 'Todo 2',
            done: false
        }];
        
        const getTodos = new Promise((res, rej) => setTimeout(res.bind(null,todos), 1000));
        
        const updateTodos = ({detail: change}) => {
            // process any change if needed (save or something?)
            console.log(change);
        }
    </script>
    
    {#await getTodos}
        Loading..
    {:then todos}
        {#each todos as todo}
            <Todo bind:todo on:change={updateTodos} />
        {/each}
        <pre>{JSON.stringify(todos,null,2)}</pre>
    {:catch error}
        {error}
    {/await}
    

    不过,如果您决定这样做,请注意不要过多地交叉数据流。

    【讨论】:

    • 感谢您的回答,我实际上事先尝试过这个解决方案,但我更喜欢 props down 事件向上模式进行组件通信。该模式是否与 {#await} 不兼容(至少对于这个用例..我认为这并不特别罕见)?
    • 不,它不兼容。除了显示结果之外,您无法对{#await} 进行任何操作,因为无法在{#await} 块本身之外获取对已解析值(此处为todos)的引用,尤其是在@987654327 中@。当您需要更多控制时,一对{#if} / {#else} 和一些由您控制的变量并不是非常多的工作。 {#await} 只是为了在最简单的情况下保存一些样板文件,我想说(这实际上也很常见)。
    • 明白,我想我将采用“用于控制加载和错误状态的额外变量”方法以及在 onMount() 中获取数据。感谢 rixo 的解释,祝您有美好的一天。
    猜你喜欢
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 2023-03-12
    • 2014-12-19
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多