当反应性值是引用类型时,苗条的输入绑定会中断?

时间:2020-03-24 05:45:11

标签: svelte-3

(我是Svelte的新手,所以很可能我在这里做错了事)

更新:我添加了另一个稍有不同的REPL,它可能会更好地演示该问题。试试这个: https://svelte.dev/repl/ad7a65894f8440ad9081102946472544?version=3.20.1


我在尝试将文本输入绑定到反应值时遇到问题。

我正努力用语言来描述问题,因此希望在随附的REPL中简化该问题的演示会更有意义。

https://svelte.dev/repl/6c8068ed4cc048919f71d87f9d020696?version=3.20.1

该演示文稿在页面上包含两个自定义<Selector>组件。


第一个组件传递了两个 string 值(“一个”和“两个”):

<Selector valueOne="one" valueTwo="two"/>

单击输入字段旁边的按钮会将selectedValue设置为这些值之一。

这反过来触发以下反应式声明进行更新:

$: value = selectedValue

输入字段绑定到此反应值:

<input type="text" bind:value>

因此,单击“一个”按钮会将输入文本设置为“一个”,然后单击“两个”按钮会将输入字段设置为“两个”。

不过,重要的是,您仍然可以在输入字段中输入任何内容


第二个组件传递了两个 array 值:

<Selector valueOne={[1, "one"]} valueTwo={[2, "two"]}/>

再次,单击按钮将selectedValue设置为其中之一。

但是这次反应式声明取决于数组元素:

$: value = selectedValue[1]

所有操作都像以前一样,但现在您再也无法在输入字段中键入

所以问题是-为什么<input bind:value>在这两个方面的行为有所不同:

$: value = aString

vs

$: value = anArray[x]

2 个答案:

答案 0 :(得分:1)

似乎只有在使用双向绑定时这才是问题。

通过切换到单向和on:input处理程序,问题消失了:

即代替这个:

x + recursion(x-1)

使用此:

<input type="text" bind:value={valX}/>

答案 1 :(得分:0)

我很确定您的反应式声明一旦更改就将覆盖您的绑定值,这与输入中的每个击键和每次按下按钮有关。从技术上讲这意味着它正在工作,您只是在每次更改时都将其还原。检出其中有观察者的this version

也绑定到反应式声明意味着您实际上不会用输入更改变量(当您键入输入时,您只能在第一个选择器的JSON结果中看到该变量,输入值不会仅在单击按钮时更新)。

为什么不丢失反应式声明并直接绑定到所需的变量。然后使用{#if}块根据index的真实性在显示的输入版本之间进行切换?

<script>
    export let valueOne;
    export let valueTwo;
    export let index;

    let selectedValue = index? [] : '';
    let selectValue = (val) => selectedValue = val;
</script>
{#if index}
    <input type="text" bind:value={selectedValue[index]} placeholder="Type anything...">
{:else}
    <input type="text" bind:value={selectedValue} placeholder="Type anything...">
{/if}
<button on:click={() => selectValue(valueOne)}>One</button>
<button on:click={() => selectValue(valueTwo)}>Two</button>
<p>
    <strong>Selected value:</strong> {JSON.stringify(selectedValue)}
</p>

通过直接绑定到selectedValue或其索引,您具有通过输入更改值的附加好处。这是REPL

中的一个有效示例