【问题标题】:How to pop array while looping with each in Svelte?如何在 Svelte 中循环时弹出数组?
【发布时间】:2021-10-26 19:49:15
【问题描述】:
<script> 
   let myMessages = ["msg1", "msg2", "msg3"]
</script>

{#each myMessages as message}
    <div>{message}</div>
{/each}

我想在 myMessages 添加到 DOM 后从 myMessages 中删除每个元素,所以最后 myMessages 为空?
(对此的一种变体是在循环中添加 {#if} 条件并仅在元素满足此条件时删除)

【问题讨论】:

  • 您的模板反映了组件/属性的状态。如果你删除了 myMessages 的元素,那么 DOM 将会改变。所以你问的不是一个好主意。
  • @JérémieB 反应性目标不是让 DOM 适应状态变化吗?当我将新元素推送到 myMessages 时,它们会更新为 DOM,这是一种正常行为,而这正是 Svelte 的设计初衷?因此,如果您对 push 有反应,您会期望对 pop 有相同的反应。不过我可能会错过一些东西。
  • 您想在从 myMessages 中删除元素时更新 DOM?您的问题是关于在渲染 DOM 后更新 myMessages
  • @JérémieB,你是对的。我的问题更多是如何知道 DOM 何时更新,所以我可以从我的变量中弹出渲染的项目。我想我必须假设它是有保证的。

标签: svelte-3


【解决方案1】:

Svelte's reactivity system 基于赋值运算符=
未检测到数组的突变(使用 pop() 之类的方法)。

myMessages.pop()
myMessages = myMessages // this line will trigger svelte to update the dom

【讨论】:

    【解决方案2】:

    如果没有关于 DOM 渲染的反馈,我会假设它。因此,要渲染 msg1 并在之后弹出它,我将按照以下步骤进行:

    <script> 
      let myMessages = []
      let tmpMessages = myMessages
      # then add msg1 to myMessages, render it and pop it
      myMessages.push("msg1")
      tmpMessages = myMessages
      myMessages.pop()
    </script>
    
    {#each tmpMessages as message}
      <div>{message}</div>
    {/each}
    

    【讨论】:

      【解决方案3】:

      这可以通过创建一个消息组件来实现,该组件在创建/安装时将自己的删除(从数组中删除)分派给父应用程序。像这样,以后可以使用相同的功能将更多消息添加到 myMessages 数组中。

      Demo REPL

      [App.svelte]
      <script>
        import { onMount } from 'svelte';
        import Message from './Message.svelte'
          
        let myMessages = ["msg1", "msg2", "msg3"]
      
      // add two additional Messages 1,5s after App creation  
      onMount( () => {
          setTimeout(function() {
            myMessages = [...myMessages, "msg4","msg5"];
          }, 1500);
      });
          
      function deleteMessage(event){
          myMessages = myMessages.slice(1)
          console.log(myMessages)
      }   
      </script>
      
      {#each myMessages as message}
          <Message {message} on:delete={deleteMessage}/>
      {/each}
      
      [Message.svelte]
      <script>
          import { onMount } from 'svelte';
          import { createEventDispatcher } from 'svelte';
          const dispatch = createEventDispatcher();
      
          export let message;
          
      onMount( () => {
          setTimeout(function() {
            dispatch('delete', {          
              });
          }, 3000);
      }); 
      </script>
      
      <div> {message} </div>
      

      或者,因为没有信息发送,只是触发了删除,没有这样的发送 -> Demo REPL

      [App.svelte]
      <script>
          import { onMount } from 'svelte';
        import Message from './Message.svelte'
          
          let myMessages = ["msg1", "msg2", "msg3"]
          
      // add two additional Messages 1,5s after App creation 
      onMount( () => {
          setTimeout(function() {
            myMessages = [...myMessages, "msg4","msg5"];
          }, 1500);
      });
          
      function deleteMessage() {
          // delete first element in arr
          myMessages = myMessages.slice(1)
          console.log(myMessages)
      }   
          
      </script>
      
      {#each myMessages as message}
          <Message {message} {deleteMessage} />
      {/each}
      
      [Message.svelte]
      <script>
          import { onMount } from 'svelte';
          
          export let message;
          export let deleteMessage;
          
      onMount( () => {
          setTimeout(function() {
              deleteMessage();
          }, 3000);
      }); 
      </script>
      
      <div> {message} </div>
      

      【讨论】:

        猜你喜欢
        • 2014-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-04
        • 2021-12-26
        • 2016-01-18
        • 1970-01-01
        相关资源
        最近更新 更多