Svelte反应性如何在函数内部工作?

时间:2019-09-17 09:08:07

标签: javascript svelte

我在Svelte中有一些严重的反应性问题。我已经隔离了我认为至少是我的主要问题之一。将变量绑定到复选框时,将变量设置在函数内部而不是外部时,反应似乎中断。这是预期的行为吗?在那种情况下为什么呢?预期的工作流程是什么?

示例代码,一个Svelte组件:

<script>
    let foo = true;

    // This assignment works both on the plain text view (Foo: true/false)
    // and on the checkbox
    // setInterval(() => foo = !foo, 500)

    // This assignment works only on the plain text view (Foo: true/false)
    // but not for the checkbox
    function action() {
        foo = !foo;
    }
</script>

Foo: { foo }<br />
Checkbox: <input type="checkbox" bind:checked={ foo } on:click|preventDefault={ action } />

简化REPL以查看此问题的实际作用:https://svelte.dev/repl/73de7d705ab3442786710cd88ea3f625?version=3.12.1

3 个答案:

答案 0 :(得分:2)

如果将变量声明包装在setTimeout中而没有任何时间限制(将其默认设置为0,因此应尽快运行),则代码将起作用。

function action() {
    setTimeout(() => {
        foo = !foo;
    });
}

我希望我能解释为什么这样做,但是我不能...

答案 1 :(得分:0)

我建议不要使用preventDefault来取消该事件,因为这将停止复选框的默认行为。

因此reactivitybroken。如果将foo的重新分配包装在setTimeout中,则只会欺骗事件循环,并且不会阻止默认事件。

因此,如果您想停止事件的传播,请使用带有来自Filip的建议的preventDefault。

    <script>
        let foo = true;

        // This assignment works both on the plain text view (Foo: true/false)
        // and on the checkbox
        // setInterval(() => foo = !foo, 500)

        // This assignment works only on the plain text view (Foo: true/false)
        // but not for the checkbox
        async function action(e) {
                e.preventDefault();
                setTimeout(() => {foo =! foo});

        }
    </script>

    Foo: { foo }<br />
    Checkbox: <input type="checkbox" bind:checked={ foo } on:click={ action } />

答案 2 :(得分:0)

似乎您的问题是由class AbstractDeviceAdapter(ABC): def __init__(self, ...): initiatlize the common attributes ... def common_method_1(self): pass def common_method_2(self): do 2 @abstractmethod def device_specific_method_0(self): pass @abstractmethod def device_specific_method_1(self): pass class Device01Adapter(AbstractAdapterInterface): def device_specific_method_0(self): do specific stuff for device 01 def device_specific_method_1(self): do specific stuff for device 01 class Device02Adapter(AbstractAdapterInterface): def device_specific_method_0(self): do specific stuff for device 02 def device_specific_method_1(self): do specific stuff for device 02 def get_device_adapter(device, ...): """ returns the Adapter appropriate for the given device """ if '01' in device.__version__: return Device01Adapter(...) if '02' in device.__version__: return Device02Adapter(...) 选项引起的。有了这个将导致 foo 进行两次更新:一次是为“操作”,一次是在绑定开始时在幕后。

只需删除bind:即可

bind:

这是有道理的,因为您不想对被检查状态为foo进行双向绑定。您只希望复选框反映 foo的值。