【问题标题】:Javascript Dynamic Data binding code not workingJavascript动态数据绑定代码不起作用
【发布时间】:2022-01-18 16:18:10
【问题描述】:

我正在编写使用数据绑定将spaninnerHTML 更改为用户输入的代码,但我无法让它工作。它应该做的是在两个输入字段的输入字段右侧显示输入,但它没有。谁能帮帮我。

HTML:

<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>My Frontend Framework</title>
    </style>
</head>
<body>
    <div>
        <label>Name:</label>
        <input type="text" bit-data="name"/>
        <span bit-data-binding="name" style="margin-left: 1rem;"></span>
    </div>

    <div>
        <label>Lastname:</label>
        <input type="text" bit-data="LastName"/>
        <span bit-data-binding="LastName" style="margin-left: 1rem;"></span>
    </div>
<script src="frontend-framework.js"></script>
</body>
</html>

Javascript:

const createState = (stateObj) => {
  return new Proxy(stateObj, {
    set(target, property, value) {
      target[property] = value;
      render();
      return true;
    }
  });
};

const state = createState({
  name: '',
  lastName: ''
});

const listeners = document.querySelectorAll('[bit-data]');

listeners.forEach((element) => {
  const name = element.dataset.model;
  element.addEventListener('keyup', (event) => {
    state[name] = element.value;
    console.log(state);
  });
});

const render = () => {
  const bindings = Array.from(document.querySelectorAll('[bit-data-binding]')).map(
    e => e.dataset.binding
  );
  bindings.forEach((binding) => {
    document.querySelector(`[bit-data-binding=${binding}]`).innerHTML = state[binding];
    document.querySelector(`[bit-data=${binding}]`).value = state[binding];
  });
}

https://jsfiddle.net/Mauro0294/g3170whc/4/

【问题讨论】:

  • “有人可以帮帮我吗” - 浏览器已经这样做了。在控制台中。带有错误消息:TypeError: document.querySelector(...) is null

标签: javascript data-binding


【解决方案1】:

您的主要问题是这部分:

const bindings = Array.from(document.querySelectorAll('[bit-data-binding]')).map(
    e => e.dataset.binding
  );

或者更具体地说是e.dataset.binding。您的元素没有data-binding 属性,这是使用dataset.binding 的先决条件。你可以改用e.getAttribute('bit-data-binding')

但是你的逻辑也有缺陷:就目前而言,将文本输入到输入中是没有意义的,因为状态永远不会更新。

最后,请注意,您在 DOM 中将 LastName 拼写为大写 L,但在状态对象中则为小写。

【讨论】:

    【解决方案2】:

    我对小提琴进行了一些更改以获得所需的结果。问题在于您使用 dataset 属性引用元素的逻辑,因此我尝试对其进行简化。

    一些显着的变化:

    1. 更新了data-bit 以使用lastName 而不是LastName。让它和你的州一样。
    2. 使用getAttribute 获取data-* 属性的值以正确获取引用。

    我想这就是你要找的东西:

    const createState = (stateObj) => {
      return new Proxy(stateObj, {
        set(target, property, value) {
          target[property] = value;
          render();
          return true;
        }
      });
    };
    
    const state = createState({
      name: '',
      lastName: ''
    });
    
    const listeners = document.querySelectorAll('[bit-data]');
    
    listeners.forEach((element) => {
      const name = element.getAttribute('bit-data');
      console.log('here', element.getAttribute('bit-data'), JSON.stringify(element.dataset))
      element.addEventListener('keyup', (event) => {
        state[name] = element.value;
        console.log(state);
      });
    });
    
    const render = () => {
      const bindings = Array.from(document.querySelectorAll('[bit-data-binding]')).map((e) => {
       return e.getAttribute('bit-data-binding');
      });
      //console.log('bindings:', bindings, document.querySelectorAll('[bit-data-binding]'));
      (bindings ?? []).forEach((binding) => {
        document.querySelector(`[bit-data-binding=${binding}]`).innerHTML = state[binding];
        document.querySelector(`[bit-data=${binding}]`).value = state[binding];
      });
    }
    <html lang="en-US">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>My Frontend Framework</title>
    </head>
    <body>
        <div>
            <label>Name:</label>
            <input type="text" bit-data="name"/>
            <span bit-data-binding="name" style="margin-left: 1rem;"></span>
        </div>
    
        <div>
            <label>Lastname:</label>
            <input type="text" bit-data="lastName"/>
            <span bit-data-binding="lastName" style="margin-left: 1rem;"></span>
        </div>
    </body>
    </html>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2017-03-18
      • 2016-12-15
      • 2017-10-21
      • 2020-04-23
      • 2018-10-30
      相关资源
      最近更新 更多