Svelte application bug: converting string to boolean in the view fails

廉价感情. 提交于 2020-07-22 05:42:07

问题


In a Svelte app, I have this array of countries:

let countries = [
    {
        name:"Alegeria",
        status: "1"
    },
    {
        name:"Bulgaria",
        status :"0"
    }
]

Note the status property is a string. I iterate the array this way:

{#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}

As you can see, I try to convert the value of the status property to a boolean this by using Boolean(Number(c.status)).

Instead of the desired conversion I get the error: Can only bind to an identifier (e.g. foo) or a member expression as the REPL shows.

What am I doing wrong?


回答1:


I think the problem is that the Boolean() function creates a new object, to which you can't bind, because it is never again referenced. You can bind directly to your array of values in countries, using this code:

{#each countries as c, index}   
    <tr>
        <td>{c.name}</td>
        <td class="text-right"><Switch bind:checked={countries[index].status} /></td>
    </tr>
{/each}

What has changed is that you use the index parameter of the #each loop now to bind to the variable of the countries array. Please be aware that in order for this to properly work, you need to change the status values to true or false. Otherwise it will still work, but the initial value will always be true.




回答2:


As it says in the error, you can only bind to an identifier or member expression - ie a variable.

This is because a bind is a two-way thing, and if you have applied Boolean(Number(()) to it, when someone changes that input, then svelte doesn't know how to undo those functions to 'save' the data back into that variable it's bound to.

If you can't change the status variables to be boolean (better solution, as suggested by other answers), you need to manually do this two-way updating. Drop the bind, just have checked={Boolean(Number(c.status))}, and handle the input's change event to convert from true/false back into "1" or "0", and save that to the status.

Use:

function handleClick(country) {
    countries.find(c => c.name == country.name).status = (country.status == "1") ? "0" :"1"
}

and

<Switch checked={Boolean(Number(c.status))} on:change={() => handleClick(c)}/>

See it working in this repl



来源:https://stackoverflow.com/questions/63014165/svelte-application-bug-converting-string-to-boolean-in-the-view-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!