Svelte 应用程序错误:在视图中将字符串转换为布尔值失败
Svelte application bug: converting string to boolean in the view fails
在 Svelte 应用中,我有这样一组国家:
let countries = [
{
name:"Alegeria",
status: "1"
},
{
name:"Bulgaria",
status :"0"
}
]
注意 status
属性 是一个字符串。我以这种方式迭代数组:
{#if countries.length > 0}
<table class="table">
<thead>
<tr>
<th>Country</th>
<th class="text-right">Status</th>
</tr>
</thead>
<tbody>
{#each countries as c}
<tr>
<td>{c.name}</td>
<td class="text-right"><Switch bind:checked={Boolean(Number(c.status))} /></td>
</tr>
{/each}
</tbody>
</table>
{:else}
<p class="alert alert-danger">No countries found</p>
{/if}
如您所见,我尝试使用 Boolean(Number(c.status))
.
将 status
属性 的值转换为布尔值
我得到的不是所需的转换,而是错误:Can only bind to an identifier (e.g.
foo) or a member expression
,如 REPL 所示。
我做错了什么?
如错误中所述,您只能 bind
标识符或成员表达式 - 即变量。
这是因为 bind
是双向的,如果您已将 Boolean(Number(())
应用到它,当有人更改该输入时,svelte 不知道如何撤消这些'save' 将数据返回到它所绑定的变量中。
如果您不能将状态变量更改为布尔值(更好的解决方案,如其他答案所建议的那样),您需要手动执行此双向更新。删除 bind
,只有 checked={Boolean(Number(c.status))}
,并处理输入的 change
事件以从 true/false 转换回“1”或“0”,并将其保存到状态.
使用:
function handleClick(country) {
countries.find(c => c.name == country.name).status = (country.status == "1") ? "0" :"1"
}
和
<Switch checked={Boolean(Number(c.status))} on:change={() => handleClick(c)}/>
查看它在 this repl
中的工作情况
我认为问题在于 Boolean() 函数创建了一个您无法绑定的新对象,因为它再也不会被引用。您可以使用以下代码直接绑定到 countries
中的值数组:
{#each countries as c, index}
<tr>
<td>{c.name}</td>
<td class="text-right"><Switch bind:checked={countries[index].status} /></td>
</tr>
{/each}
改变的是您现在使用 #each
循环的 index
参数绑定到国家数组的变量。请注意,为了使其正常工作,您需要将状态值更改为 true
或 false
。否则它仍然有效,但初始值将始终为 true
.
如果您只想将值传递给 Switch
组件,只需像这样删除 bind:
:
<td class="text-right"><Switch checked={Boolean(Number(c.status))} /></td>
如果您想通过切换组件更新国家/地区模型,我建议转发点击事件并使用简单的点击处理方法,如下所示:
function onClick(event, country) {
countries = countries.map(c => {
if (c.name === country.name) {
c.status = event.target.checked ? '1' : '0';
}
return c;
})
}
...
<td class="text-right"><Switch checked={c.status === '1'} on:click={(e) => onClick(e, c)}/></td>
REPL 上的完整代码:https://svelte.dev/repl/013286229d3847c1895c4977aee234af?version=3.9.1
在 Svelte 应用中,我有这样一组国家:
let countries = [
{
name:"Alegeria",
status: "1"
},
{
name:"Bulgaria",
status :"0"
}
]
注意 status
属性 是一个字符串。我以这种方式迭代数组:
{#if countries.length > 0}
<table class="table">
<thead>
<tr>
<th>Country</th>
<th class="text-right">Status</th>
</tr>
</thead>
<tbody>
{#each countries as c}
<tr>
<td>{c.name}</td>
<td class="text-right"><Switch bind:checked={Boolean(Number(c.status))} /></td>
</tr>
{/each}
</tbody>
</table>
{:else}
<p class="alert alert-danger">No countries found</p>
{/if}
如您所见,我尝试使用 Boolean(Number(c.status))
.
status
属性 的值转换为布尔值
我得到的不是所需的转换,而是错误:Can only bind to an identifier (e.g.
foo) or a member expression
,如 REPL 所示。
我做错了什么?
如错误中所述,您只能 bind
标识符或成员表达式 - 即变量。
这是因为 bind
是双向的,如果您已将 Boolean(Number(())
应用到它,当有人更改该输入时,svelte 不知道如何撤消这些'save' 将数据返回到它所绑定的变量中。
如果您不能将状态变量更改为布尔值(更好的解决方案,如其他答案所建议的那样),您需要手动执行此双向更新。删除 bind
,只有 checked={Boolean(Number(c.status))}
,并处理输入的 change
事件以从 true/false 转换回“1”或“0”,并将其保存到状态.
使用:
function handleClick(country) {
countries.find(c => c.name == country.name).status = (country.status == "1") ? "0" :"1"
}
和
<Switch checked={Boolean(Number(c.status))} on:change={() => handleClick(c)}/>
查看它在 this repl
中的工作情况我认为问题在于 Boolean() 函数创建了一个您无法绑定的新对象,因为它再也不会被引用。您可以使用以下代码直接绑定到 countries
中的值数组:
{#each countries as c, index}
<tr>
<td>{c.name}</td>
<td class="text-right"><Switch bind:checked={countries[index].status} /></td>
</tr>
{/each}
改变的是您现在使用 #each
循环的 index
参数绑定到国家数组的变量。请注意,为了使其正常工作,您需要将状态值更改为 true
或 false
。否则它仍然有效,但初始值将始终为 true
.
如果您只想将值传递给 Switch
组件,只需像这样删除 bind:
:
<td class="text-right"><Switch checked={Boolean(Number(c.status))} /></td>
如果您想通过切换组件更新国家/地区模型,我建议转发点击事件并使用简单的点击处理方法,如下所示:
function onClick(event, country) {
countries = countries.map(c => {
if (c.name === country.name) {
c.status = event.target.checked ? '1' : '0';
}
return c;
})
}
...
<td class="text-right"><Switch checked={c.status === '1'} on:click={(e) => onClick(e, c)}/></td>
REPL 上的完整代码:https://svelte.dev/repl/013286229d3847c1895c4977aee234af?version=3.9.1