【问题标题】:Benign cyclical dependencies良性循环依赖
【发布时间】:2020-05-07 08:34:43
【问题描述】:

为一个新项目尝试 svelte 我编写了一个组件来编辑一个复合对象,它将单个部件的编辑委托给子组件,并在部件更改时重新创建复合对象。当然,当复合对象被外部更改时,子组件应该更新为新值。

我最终得到了以下结果:

<script>  
    let item = "content";
    export let holder = { item };

    $: {
        console.log("setting item to "+holder.item);
        item = holder.item;
    }

    $: setHolder(item);

    function setHolder(i) {
        console.log("setting holder for "+i);
        holder = { item: i }
    }
</script>

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

上述编译但内容无法编辑,因为当编辑item 时,第一个反应块被执行,将变量设置回holder.item

我不明白以下内容:

  • 为什么要执行第一个反应块?由于item 仅出现在赋值的左侧,它不是它所依赖的值。
  • 为什么循环依赖对编译器“隐藏”,为什么下面的工作不起作用?
    $: {
        console.log("setting item to "+holder.item);
        item = holder.item;
    }

    $: {
        console.log("setting holder for "+item);
        holder = { item }
    }
  • 为什么将两个响应式块包装到函数中时一切正常?
    $: setItem(holder)
    function setItem(h) {
        console.log("setting item to "+h.item);
        item = h.item;
    }

    $: setHolder(item);
    function setHolder(i) {
        console.log("setting holder for "+i);
        holder = { item: i }
    }

依赖编译器以某种方式看不到代码在做什么似乎很奇怪,所以我想知道我是否有一个完全错误的方法。

【问题讨论】:

    标签: svelte svelte-3 svelte-component


    【解决方案1】:

    每当提及的任何变量发生变化时,都会重新执行反应式语句。因此,当holderitem 更改时,您的第一条语句将重新运行。

    函数方法很有效,因为突然间你只提到了一个变量(编译器只在直接块中查找,而不是在任何将被调用的函数内部)

    我承认一开始有点混乱,但希望这能让它更清楚一点

    【讨论】:

    • 虽然我同意您的评估,但我仍然无法理解为什么在 setHolder 更新 holder 后未触发 setItem(它应该因为已分配 holder一个全新的对象?)即使在函数形式中,我们这里也应该有一个非法的循环依赖,还是我遗漏了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2021-10-02
    • 1970-01-01
    相关资源
    最近更新 更多