【问题标题】:Append item to last object in Svelte Store将项目附加到 Svelte Store 中的最后一个对象
【发布时间】:2021-11-12 09:00:34
【问题描述】:

我正在尝试创建一个 Svelte 应用程序,将国际象棋移动存储在一个数组中。每次创建新的白色移动时,都应在数组中创建一个新对象。创建黑色移动应该简单地更新最后一个对象中的字段black_move。但是,在再次按下白色移动按钮之前,输出不会对此更新做出反应。可能是什么问题? REPL 是here

import { writableArray } from './store.js';
    
    const moveWhite = () => {
        $writableArray = [...$writableArray, {
            white_move: 'a1-a2',
            black_move: ''
        }];
    };
    const moveBlack = () => {
        $writableArray.at(-1).black_move = 'b1-b2' 
    };
  
<button on:click={moveWhite}>
    Move White
</button>
<button on:click={moveBlack}>
    Move Black
</button>

{#each $writableArray as item}
    {item.white_move} {item.black_move}
{/each}

商店定义如下:

import { writable } from 'svelte/store';

export const writableArray = writable([]);

【问题讨论】:

    标签: svelte


    【解决方案1】:

    你可以使用update方法,比如:

    writableArray.update(existingValue => ([...existingValue, newMove]));
    

    所以你的例子看起来像:

    <script>
        import { writableArray } from './store.js';
        
        const moveWhite = () => {   
            writableArray.update(s => ([...s, {
                white_move: 'a1-a2',
                black_move: ''
            }]));
        };
        
        const moveBlack = () => {       
            writableArray.update(s => {
                s.at(-1).black_move = 'b1-b2'           
                
                return s
            });
        };
    </script>
    

    【讨论】:

      【解决方案2】:

      我认为使用作业

      const moveBlack = () => {
              $writableArray.at(-1).black_move = 'b1-b2' 
              $writableArray = $writableArray
          };
      

      对于组件内部来说是一个很好的解决方案,因为它比使用.update() 更简洁一些。就像已经提到的,扩展运算符不是必需的,重要的是赋值。查看文档'assignments are "reactive"'

      为了展示另一种方法,除了在 App.svelte 中声明函数之外,您还可以创建一个自定义存储并将它们放在那里 -> REPL

      store.js
      import {writable} from 'svelte/store'
      
      export const movesArray = (() => {
          const {subscribe, set, update} = writable([])
          return {
              subscribe,
      //      set, // optional if needed outside store
      //      update, // optional if needed outside store
              moveWhite() {
                  update(store => {
                      return [...store, { white_move: 'a1-a2', black_move: ''}]
                  })
              },
              moveBlack(move) {
                  update(store => {
                      store.at(-1).black_move = move
                      return store // this line is important
                  })
              }       
          }   
      })();
      
      App.svelte
      <script>
          import { movesArray } from './store.js';        
      </script>
      
      <button on:click={movesArray.moveWhite}>
          Move White
      </button>
      <button on:click={() => movesArray.moveBlack('b1-b2')}>
          Move Black
      </button>
      
      {#each $movesArray as item}
      <p>
          {item.white_move} {item.black_move}
      </p>
      {/each}
      

      【讨论】:

      • 我不得不说,我最喜欢这个答案。所有答案都有效,但这使得与其他模块的商店界面更清晰。
      【解决方案3】:

      我发现以下方法也有效,但由于我是 Svelte 新手,我不确定这是推荐的方法:

      const moveBlack = () => {
              $writableArray.at(-1).black_move = 'b1-b2' 
              $writableArray = [...$writableArray]
          };

      【讨论】:

      • $writableArray = $writableArray 也不需要扩展运算符,只需要更新值即可。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多