数据双向绑定,即在视图层 view上修改数据时,要将 js 数据模型层 model 上的数据也同步更改;同理修改数据模型层上的数据时,也要将视图层的数据更新。
视图上数据修改,同步至模型层。首先想到的是,通过事件监听在处理函数中去修改模型层数据。那么修改模型层,如何更新到视图层呢?这里就需要引入一个方法了,Object.defineProperty()
。
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
- 语法:
Object.defineProperty(obj, prop, descriptor)
- 参数:
obj,目标对象。
prop,要定义或修改的属性的名称。
descriptor,将被定义或修改的属性描述符。
-
属性描述符 descriptor:
value:属性的值
writable:如果为false,属性的值就不能被重写。
get:一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。
set:一旦目标属性被赋值,就会调回此方法。
configurable:如果为false,则任何尝试删除目标属性或修改属性性以下特性(writable, configurable, enumerable)的行为将被无效化。
enumerable:定义属性是否为枚举属性,即是否能在for...in循环中遍历出来或在Object.keys中列举出来。
通过Object.defineProperty()
中,对 set 方法的描述,就有了 “修改模型层,更新视图层 ” 的解决办法了。
数据双向绑定实现思路:view——>model,事件监听,当用户修改输入框文字时触发,在回调处理函数中修改model数据;model——>view,Object.defineProperty()
中的 set 方法,当 model 中的数据被修改时,set 方法会执行,因此可在 set 方法来操作视图 DOM,更新 view 中的值。
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Object.defineProperty()实现数据双向绑定</title>
</head>
<body>
<input type="text" id="userName">
<p id="userName2"></p>
<script>
var user = {};
Object.defineProperty(user, "name", {
get: function () {
console.log("getִ执行")
},
set: function (val) {
console.log("setִ执行")
document.getElementById("userName2").innerHTML = val // 更改model,更新view
document.getElementById("userName").value = val // 更改model,更新view
}
})
document.getElementById("userName").addEventListener("keyup", function (event) {
user.name = event.target.value // 更改view,更新model
})
</script>
</body>
</html>
.
【1】慕课网
【2】https://juejin.im/entry/589ff26486b599006b3dea9b
【3】https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty