2

我的问题在于我正在制作的申请表中需要填写大量输入。我正在使用 Hyperscript 生成 HTML,我遇到了一个问题,当我在页面中生成更多元素时,我会丢失来自输入的信息,但只有在我删除位于输入之前的一些 HTML 并更新 Web 的情况下。在示例中,我遇到了原始类型的问题,其中我在用户提供信息的输入之前生成了警告(说要填写信息),但是一旦再次生成 HTML 而没有警告,输入也会丢失。您知道如何在不移动警告的情况下保留输入并生成新的 HTML 吗?通过查看示例,您可以更好地理解问题 - 您按照警告的建议填写输入,然后单击以生成其他 HTML,但它会删除输入,您必须再次填写。

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <div id="app">

    </div>
    
    <!-- Peryl import -->
    <script src="https://unpkg.com/peryl@1.4.22/incremental-dom/dist/umd/incremental-dom.js"></script>
    <script src="https://unpkg.com/peryl@1.4.22/dist/umd/hsml-h.js"></script>
    <script src="https://unpkg.com/peryl@1.4.22/dist/umd/hsml-app.js"></script>
    <!-- end Peryl import -->
    <script>
        const state = {
            warning: "Please fill Temperature parameter",
            showDiv: false
        }

        function getWarning() {
            if (state.warning !== "") {
                return h("div#warning", {style:"color: red;"}, state.warning);
            }
        }

        function getDiv() {
            if (state.div) {
                return h("div", "The div is visible but input is gone");
            }
        }

        function view() {
            return [
                getWarning(),
                h("label", "Temperature"),
                h("input", {type:"text"}),
                h("button", {
                    on:["click", "showDiv"]
                }, "showDiv"),
                getDiv()
            ];
        }

        function dispatcher(app, action) {
            if (action.type === "showDiv") {
            state.warning = "";   // warning get's cleaned when it's filled
            state.div = !state.div;
            }
            app.update(); 
        }
        new HApp(state, view, dispatcher)
            .mount(document.getElementById("app"));
    </script>
  </body>
</html>
4

1 回答 1

4

所描述的问题是通过 HSML 下的增量 dom 引擎渲染 DOM 节点给出的。

这与渲染列表(例如在 React 中的虚拟 dom 中)类似,其中标记列表节点的最佳实践是key帮助渲染引擎管理节点重新排序。

div#app示例中的node 下有一个 DOM 节点列表。列表节点之一是输入元素。IDOM 引擎无法识别节点重新排序,因此引擎会呈现所有新节点并在您打乱元素时丢弃旧节点。因此,带有其值的输入将被删除并替换为包含空值的新输入。

要解决问题,您必须使用_key属性标记输入元素,以帮助渲染引擎在节点洗牌期间识别节点,如下所示:

h("input", { _key: "some-input-key", type: "text" }).
于 2020-12-12T15:12:51.307 回答