原生js雙向資料繫結

weixin_34377065發表於2018-03-02

前面我們介紹過儲存器屬性(重新認識javascript物件(一)——物件及其屬性),以及如何用Object.defineProperty()定義一個儲存器屬性,今天我們介紹如何用Object.defineProperty()實現雙向資料繫結。

我們知道一個儲存器屬性有四個屬性描述符:get,set,configurable,enumerable。我們來複習一下如何建立一個儲存器屬性:

var user = {
    name: ''
}
Object.defineProperty(user, 'nickname', {
    configurable: true,
    enumerable: true,
    get: function() {
        return this.name
    },
    set: function(value) {
        this.name = value
    }
})
複製程式碼

以上程式碼我們給user建立了一個名為nickname的儲存器屬性。

接下來我們改寫getset,讓它們與DOM繫結,並實現雙向資料繫結,以下為具體實現的虛擬碼:

<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,具體實現如下:

<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,以下程式碼也可以實現雙向資料繫結:

<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>
複製程式碼

相關文章