Javascript 动态数据绑定代码不工作
Javascript Dynamic Data binding code not working
我正在编写使用数据绑定将 span
的 innerHTML
更改为用户输入的代码,但我无法让它工作。它应该做的是在两个输入字段的输入字段右侧显示输入,但事实并非如此。谁能帮帮我。
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];
});
}
你的主要问题是这部分:
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 中用大写 L
拼写 LastName
,但在状态对象中拼写为小写。
我对 fiddle 进行了一些更改以获得所需的结果。问题在于您使用 dataset
属性引用元素的逻辑,因此我尝试对其进行简化。
一些显着的变化:
- 更新了
data-bit
以使用lastName
而不是LastName
。让它和你的州一样。 - 使用
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>