【问题标题】:dom not updating when object is changed更改对象时dom不更新
【发布时间】:2020-11-02 13:26:40
【问题描述】:

我有一个我认为是一个非常小而简单的苗条网络应用程序,目前只是一个问卷调查。我正在尝试创建一种多选系统,您可以在其中单击一堆按钮并将它们标记为选中(几乎是一个 html 复选框,但有点离题)。

所以为了向用户显示一个选项被选中,如果它被选中,我想向按钮添加一个类。但是它没有被更新,我真的不知道为什么。 isSelected 函数每个选项只调用一次,并且在修改设置对象时从不调用,我想知道为什么会这样

    <script>
      let page = 0;
      let setup = {
        JLPT: {
          question: "select JLPT levels",
          options: [1, 2, 3, 4, 5, 6, 7, 8, 9],
          selected: [],
          onSelect: option => {
            console.log(setup.JLPT.selected);
            setup.JLPT.selected = setup.JLPT.selected.concat(option);
          }
        }
      };
      $: question = getQuestion(page);
    
      function getQuestion(page) {
        return setup[Object.keys(setup)[page || 0]];
      }
    
      function isSelected(option) {
        return (question.selected || []).indexOf(option) > -1;
      }
    
      function onClick(option) {
        getQuestion(page).onSelect(option);
      }
    </script>
    
    
    <div class="wrapper">
      <div class="question">{question.question}</div>
      <div class="input">
        {#each question.options as option}
          <button
            on:click={() => onClick(option)}
            class={isSelected(option) ? 'selected' : ''}>
            {option}
          </button>
        {/each}
      </div>
    </div>

【问题讨论】:

    标签: svelte


    【解决方案1】:

    $: question = getQuestion(page); 替换为:

    $: question = setup[Object.keys(setup)[page || 0]];
    

    https://svelte.dev/repl/f7c2a4119829442a8e46ebb557bf1cf8?version=3.29.4

    为什么?

    反应式声明的工作方式是,svelte 解析它并提取它所依赖的参数。在$: question = getQuestion(page); 的情况下,依赖项是getQuestionpage,每当它们中的任何一个发生变化时,都会重新计算question

    但是getQuestionpage 永远不会改变,所以question 永远不会重新计算。

    因此,您想要的是,每当setup 发生变化时重新计算question,为此您需要确保question 依赖于setup

    换句话说,您需要反应式声明才能拥有这种形式

    $: question = ...setup...
    

    这条原则也发生在这一行

    class={isSelected(option) ? 'selected' : ''}
    

    Svelte 对其进行解析,并将 isSelectedoption 提取为依赖项,并在其中任何一个发生更改时重新计算“类属性”。

    但现在你可能会想...... 嘿!但他们永远不会改变,那么这到底是怎么回事?

    原因是option 是依赖于question#each block 的一部分,而question 又依赖于setup
    因此,每当setup 更改(标记为“脏”)时,question 就会被重新计算并标记为“脏”,因此每个“类属性”都会被重新计算,因为它们都间接依赖于question


    顺便说一句:动态分配类的更好解决方案是使用the class directive

    class:selected={isSelected(option)}
    

    您可能想阅读这篇帖子 https://lihautan.com/compile-svelte-in-your-head-part-2/#reactive-declaration,以更好地了解 Svelte 在 反应式声明

    中所做的事情

    【讨论】:

      猜你喜欢
      • 2018-01-15
      • 2015-09-06
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多