【问题标题】:How does javascript create one-way data binding with DOM elements?javascript 如何创建与 DOM 元素的单向数据绑定?
【发布时间】:2019-08-10 01:03:46
【问题描述】:

我不知道“单向数据绑定”是否真的是正确的定义,但是我有一个名为timesheetRow 的类,它在调用时表示表中的一行。

该类有一个名为generateRow() 的方法,它将<td> 元素绑定到对象属性,然后将它们全部附加到父<tr> 元素。我这样做是因为在返回行之前,我必须添加一些事件侦听器以进行验证。代码是这样的:

class timesheetRow{

    generateRow(){

        this.row = htmlToElement(`
            <tr>
            </tr>
        `);

        this.nodes.workHours = htmlToElement(`
            <td>
                <input name="workHours" 
                min=0 
                max=24 
                class="form-control workHours" 
                type="number">
            </td>
        `);

        this.nodes.workProject = htmlToElement(`
            <td>
                <select name="workProject" 
                class="form-control workProject" 
                required>
                    <option disabled selected value="">Sin proyecto asignado</option>
                    <option value="1">Proyecto 1</option>
                </select>
            </td>
        `);

        this.nodes.workHours.addEventListener("input", event => {
            this.row.querySelector('.workProject').disabled = parseInt(event.target.value) < 1;
        });

        for (let node in this.nodes) {
            this.row.appendChild(this.nodes[node]);
        }

        return this.row;
    }
}

这是实际代码的一个非常精简的版本,但我希望它能澄清我的问题。

如果您查看我添加到 workHours 元素中的事件侦听器,它会直接作用于存储为我的对象属性之一的行,但更改该属性也会自动更改 DOM。所以,据我所知,这看起来像是单向数据绑定。当 workHours 值低于 1 时,workProject 选择元素被禁用。我不是直接更改 DOM,而是更改我的对象。

我想知道这里的幕后情况。提前感谢任何花时间回答我的问题的人!

【问题讨论】:

  • htmlToElement 是什么?
  • 我创建的一个辅助函数,用于使用模板将字符串转换为元素。 @SergiuParaschiv
  • 这里没有绑定,只是你存储对Dom节点的引用,..

标签: javascript html class dom ecmascript-6


【解决方案1】:

this.row.querySelector('.workProject') 返回一个对 DOM Node 的引用,它是一个表示 DOM Node 的对象。

disabledselect 节点上的一个属性,它操纵浏览器呈现它的方式。当您更改 disabled 属性时,渲染引擎本身知道它需要重绘输入。

没有魔法。

  1. 您在输入中输入内容,input 事件被调度

  2. 您在 input 上添加了一个 input 侦听器,因此每次 (1) 发生时都会调用该侦听器

  3. 您的侦听器获得对 select 的引用并更改其属性

  4. 负责渲染 DOM 的浏览器/事物的设计方式是:更改 selects 上的 disabled 属性会达到预期效果

还有this.row.querySelector('.workProject') !== this.nodes.workProject

【讨论】:

  • this.row.querySelector('.workProject') 不是对对象的 row 属性的引用吗?(这是一个虚拟 DOM 元素)。它没有像 document.querySelector() 那样引用 dom 本身。
  • 对,但是“虚拟 DOM”仍然是 DOM,就像您的主文档 DOM 一样,没有什么特别之处。当您将其导入“主”DOM 时,它就是其中的一部分。
  • 所以我们可以说将虚拟 DOM 元素添加到“主”DOM 会创建单向数据绑定关系?
  • 没有。与数据绑定无关。数据绑定是人们将 UI 框架命名为特性的东西,DOM/浏览器没有定义这样的东西。您在这里拥有的是基本的 DOM 操作和事件,增加了“虚拟 DOM”的复杂性,在您的情况下,这只是生成 DOM 片段的一种简单方法。但是,是的,没有人阻止你称它为任何东西:)
  • 所以从技术角度来说,“主”DOM 元素以某种方式指向我对象的 row 属性,并且知道它得到的任何更改,是否需要更新?
猜你喜欢
  • 1970-01-01
  • 2013-01-23
  • 2012-07-05
  • 2011-03-02
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多