将项目附加到 Svelte Store 中的最后一个对象
Append item to last object in Svelte Store
我正在尝试创建一个 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([]);
您可以使用 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>
我发现以下方法也有效,但由于我是 Svelte 的新手,我不确定这是推荐的方法:
const moveBlack = () => {
$writableArray.at(-1).black_move = 'b1-b2'
$writableArray = [...$writableArray]
};
我认为使用作业
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}
我正在尝试创建一个 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([]);
您可以使用 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>
我发现以下方法也有效,但由于我是 Svelte 的新手,我不确定这是推荐的方法:
const moveBlack = () => {
$writableArray.at(-1).black_move = 'b1-b2'
$writableArray = [...$writableArray]
};
我认为使用作业
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}