前面我们介绍过存储器属性(重新认识JS对象(一)-- 对象及其属性),以及如何用Object.defineProperty()
定义一个存储器属性,今天我们介绍如何用Object.defineProperty()
实现双向数据绑定。
我们知道一个存储器属性有四个属性描述符:get,set,configurable,enumerable
。我们来复习一下如何创建一个存储器属性:
1 2 3 4 5 6 7 8 9 10 11 12 13
| var user = { name: '' } Object.defineProperty(user, 'nickname', { configurable: true, enumerable: true, get: function() { return this.name }, set: function(value) { this.name = value } })
|
以上代码我们给user
创建了一个名为nickname
的存储器属性。
接下来我们改写get
和set
,让它们与DOM
绑定,并实现双向数据绑定,以下为具体实现的伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <input type="text" id="foo">
<script> var user = {} Object.defineProperty(user, 'inputValue', { configurable: true, get: function() { return document.getElementById('foo').value }, set: function(value) { document.getElementById('foo').value = value } }) </script>
|
我们打开控制台,改变user.inputValue
的值,会发现input
输入框里的值也发生变化;同样我们在input
输入框里面输入值,在控制台打印user.inputValue
,会发现user.inputValue
也发生了变化。这样我们就实现了双向的数据绑定。
如果多个DOM
绑定同一个数据,我们可以监听input
输入框的keyup
事件,只要触发了keyup
事件我们就把user.inputValue
的值赋给另一个DOM
,具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <input type="text" id="foo"> <p id="test"></p>
<script> var user = {} Object.defineProperty(user, 'inputValue', { configurable: true, get: function() { return document.getElementById('foo').value }, set: function(value) { document.getElementById('foo').value = value document.getElementById('test').innerHTML = value } }) document.getElementById('foo').addEventListener('keyup',function() { document.getElementById('test').innerHTML = user.inputValue })
|
最后附上源码图片
思考:其实实现双向数据绑定并不一定要用Object.defineProperty()
,其主要是运用存储器属性的get和set
,以下代码也可以实现双向数据绑定:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <input type="text" id="foo"> <p id="test"></p>
<script> var user = { get inputValue() { return document.getElementById('foo').value }, set inputValue(value) { document.getElementById('foo').value = value document.getElementById('test').innerHTML = value } } document.getElementById('foo').addEventListener('keyup',function() { document.getElementById('test').innerHTML = user.inputValue }) </script>
|