LIT-HTML 在呈现下拉列表时仍然使用先前的下拉选择索引

问题描述 投票:0回答:1

我正在使用 Lit-HTML(不是 Lit-Element)来构建 html 表单。表格非常简单,它有 2 个下拉菜单:Population 下拉菜单和 Animal 下拉菜单。

动物下拉选项取决于人口下拉列表的选择。请参阅 getAnimalDS() 逻辑。

模型定义和实用函数:

const model = {
    Population: null,
    Animal: null,
}

const dataSources = {
    Populations: [null, "p1", "p2"],
    Animals_1:   [null, "a1", "a2"],
    Animals_2:   [null, "a3", "a4", "a5"],
}

function getAnimalDS(population) {
    switch (population) {
        case 'p1':
            return dataSources.Animals_1;
        case 'p2':
            return dataSources.Animals_2;
        default:
            return [];
    }
}

构建LIT-HTML模板的主要功能:

function buildSection1(model) {
    return html`
    
    <div class="mb-3">
        <label for="Population" class="form-label">Population</label>
        <select id="Population" name="Population" class="form-control"
            .value="${model.Population}" @change=${e
                  => {
                            model.Population = e.target.value;
                            model.Animal = null; // Reset Animal
                            renderSection1(); // Re-render the form
                     }}>

            ${dataSources.Populations.map((item) => html`
                    <option value="${item}" ?selected="${model.Population === item}">${item}</option>
            `)}
        </select>
    </div>

    <div class="mb-3">
        <label for="Animal" class="form-label">Animal</label>
        <select id="Animal" name="Animal" class="form-control"
            .value="${model.Animal}" @change=${e => model.Animal = e.target.value}>

            ${getAnimalDS(model.Population).map((item) => html`
                    <option value="${item}" ?selected="${model.Animal === item}">${item}</option>
            `)}
        </select>
    </div>

    `;
}

测试:

如果我在 Population 下拉列表中选择一个 population,我会看到 Animal 上的选项正确更改 -> Awesome.

查看问题的步骤:

#1:在 Population 下拉列表中选择选项“p1”,我在 Animal 下拉列表中看到 3 个选项:“”、'a1'、'a2' -- Good

#2:接下来,我在动物下拉列表中选择“a2”(选定索引 = 2)-> 好

#3:现在,在 Population 下拉列表中选择选项“p2”,我在 Animal 下拉列表中看到 4 个选项:“”、'a3'、'a4'、'a5' -> Good

#4:在这一点上,我希望在 Animal 下拉列表中看到“EMPTY”行(选择的索引 = -1),因为在 @change of the Population 上,我确实将 model.Animal 重置为 null。

---- 但是 Animal 下拉菜单显示选项“a4”(选定索引 = 2)

---- 这意味着 LIT-HTML 在步骤 #2 使用先前选择的索引 = 2。

有意见吗?谢谢!

javascript html dom lit-element lit-html
1个回答
0
投票

此行为的原因是因为 lit-html 不知道第二个

<select id="Animal">
元素的值已更改,因为
@change
事件处理程序将
model.Animal
更改为
'a2'
但不调用
render()
再次。由于 lit-html 认为该值仍然是
null
,因此在重新渲染时不会更新 DOM。

解决方案 1:您可以通过在此处添加

renderSection1()
调用来解决此问题,例如:

html`
  ...
  <select id="Animal" name="Animal" class="form-control"
    .value="${model.Animal}"
    @change=${e => {
      model.Animal = e.target.value;
      renderSection1();
    }}>
  ...
  </select>`

让 lit-html 知道值已经更新。因此,当第一个下拉列表将值更改回

null
时,它知道它再次不同并更新DOM。

解决方案 2:或者,您也可以使用

live()
指令使 lit-html 始终根据 DOM 值检查值

import {live} from 'lit-html/directives/live.js';

html`
  ...
  <select id="Animal" name="Animal" class="form-control"
    .value="${live(model.Animal)}" // always compare against DOM
    @change=${e => model.Animal = e.target.value}>
  ...
  </select>`
© www.soinside.com 2019 - 2024. All rights reserved.