繫結

什麼是約束力

基本上,繫結或資料繫結是將 ViewModel 連結到 Views(模板)的一種方式,反之亦然。KnockoutJS 使用雙向資料繫結,這意味著對 ViewModel 的更改會影響 View,而對 View 的更改可能會影響 ViewModel。

引擎蓋下(簡短概述)

繫結只是允許你解決特定任務的外掛(指令碼)。根據你的 ViewModel,此任務通常是更改標記(html)。

例如,text 繫結允許你在 ViewModel 更改時顯示文字並動態更改它。

KnockoutJS 帶有許多強大的繫結,並允許你使用自己的自定義繫結進行擴充套件。

最重要的是繫結並不神奇,它們根據一組規則工作,任何時候你不確定繫結的作用,它需要什麼引數或何時更新檢視你可以參考繫結的原始碼。

請考慮以下自定義繫結示例:

ko.bindingHandlers.debug = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.computed(function () {
            var value = ko.unwrap(valueAccessor());
    
            console.log({
                value: value,
                viewModel: viewModel,
                bindingContext: bindingContext
            });
        }, null, { disposeWhenNodeIsRemoved: element });
    }
};
  1. 繫結有一個名稱 - debug 所以你可以使用如下:

data-bind="debug: 'foo'"

  1. 啟動繫結時,會呼叫 init 方法一次。其餘的更新由匿名計算處理,該計算在刪除 element 時處理。
  2. 繫結列印到控制檯的幾件事:在我們的例子中傳遞的值這個值是 foo(這個值也可以是可觀察的,因為 ko.unwrap 方法用於讀取它),當前的 viewModel 和 bindingContext。
  3. 每當傳遞的值更改時,繫結都會將更新的資訊列印到控制檯。
  4. 此繫結不能與虛擬元素(在 html 註釋中)一起使用,僅適用於真實元素,因為 ko.virtualElements.allowedBindings.debug 標誌未設定為 true。

何時使用括號

沒有任何額外的外掛 ,KnockoutJS 將只能檢視 ViewModel 上可觀察的屬性的實時 View 更新 (常規 observable,還有 computedpureComputedobservableArray 等)。可以像這樣建立一個 observable:

var vm = { name: ko.observable("John") };

在這種情況下,vm.name 是一個具有兩個獨立模式函式

  1. Getter:vm.name(),沒有引數,將獲得當前值;
  2. Setter:vm.name("Johnnyboy"),帶引數,將設定一個新值。

在內建資料繫結中,你始終可以使用 getter 表單,有時你實際上可以省略括號,繫結將為你有效地新增它們。所以這些是等價的:

<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too

但這會失敗:

<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!

因為只要在將值傳遞給資料繫結(包括值比較)之前想要執行某些操作,就需要正確獲取所有可觀察物件的值,例如:

<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works

有關更多詳細資訊,請參閱此問答