[英]Is it possible in Svelte to have #each loops with two-way binding to nested object values?
以下 Svelte 代碼運行良好:
<input bind:value='options.name.value' placeholder='{{options.name.placeholder}}'>
<p>Hello {{options.name.value || 'stranger'}}!</p>
使用這個 JSON:
{
"options": {
"name": {
"value": "",
"placeholder": "enter your name"
}
}
}
您可以看到它的實際效果。 但是,如果我們想使用#each
數組遍歷options
怎么辦……這可能嗎?
如果我們做除了綁定之外的所有事情,它幾乎可以工作:
{{#each Object.keys(options) as option}}
<input bind:value='options.name.value' placeholder='{{options[option].placeholder}}'>
<p>Hello {{options[option].value || 'stranger'}}!</p>
{{/each}}
可以看到占位符是正確的,雙向綁定工作正常。 但是代碼還不正確,因為options.name
是為綁定而硬編碼的,而不是使用循環值。 如果我們嘗試修復它,放置bind:value='options[option].value'
,我們會得到一個語法錯誤, Expected '
。
那么,如果可以使用循環值在循環內進行雙向綁定,那么正確的語法是什么?
簡短的回答是,是的,絕對可以在each
塊內使用雙向綁定,但塊的值必須是一個簡單的數組,而不是像Object.keys(options)
這樣的表達式的結果:
{#each options as option}
<input bind:value={option.value} placeholder={option.placeholder}>
{/each}
{
"options": [
{
"id": "name",
"value": "",
"placeholder": "enter your name"
},
{
"id": "email",
"value": "",
"placeholder": "enter your email"
}
]
}
更長的答案,我在其中大聲思考了一會兒:使用表達式(不僅僅是像foo
這樣的引用或像foo.bar
這樣的非計算成員表達式)進行雙向綁定是一個有趣的挑戰。 實際上有兩個獨立的問題:首先,區分像options[option].value
這樣的有效表達式和在雙向綁定上下文中沒有任何意義的表達式。 其次, each
塊表達式創建了一種障礙——如果有人要這樣做......
{#each Object.keys(options) as option}
<input bind:value={option}>
{/each}
...它們將綁定到一個本質上是只讀的值。 但是你不能僅僅從語法上看出這一點。 所以靜態分析需要足夠聰明才能理解綁定到options[option].name
是有效的,但綁定到option
不是。 值得我們思考的東西。
最后,秘密選項是不在此上下文中使用雙向綁定,因為它實際上只是一個方便的事件偵聽器包裝器:
<script>
let options = {
name: {
value: '',
placeholder: 'enter your name'
}
};
function updateValue(option, value) {
options[option].value = value;
}
</script>
{#each Object.keys(options) as option}
<input
on:input="{() => updateValue(option, e.target.value)}"
placeholder={options[option].placeholder}
>
{/each}
<script>
let options = {
name: {
value: '',
placeholder: 'enter your name'
},
};
$: console.table(options)
</script>
{#each Object.entries(options) as [key, option]}
<input
bind:value={option.value}
placeholder={option.placeholder}
>
{/each}
https://svelte.dev/repl/a77dd18da023469da962d873e6fb391f?version=3.47.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.