繫結
什麼是約束力
基本上,繫結或資料繫結是將 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 });
}
};
- 繫結有一個名稱 -
debug
所以你可以使用如下:
data-bind="debug: 'foo'"
- 啟動繫結時,會呼叫
init
方法一次。其餘的更新由匿名計算處理,該計算在刪除element
時處理。 - 繫結列印到控制檯的幾件事:在我們的例子中傳遞的值這個值是
foo
(這個值也可以是可觀察的,因為ko.unwrap
方法用於讀取它),當前的 viewModel 和 bindingContext。 - 每當傳遞的值更改時,繫結都會將更新的資訊列印到控制檯。
- 此繫結不能與虛擬元素(在 html 註釋中)一起使用,僅適用於真實元素,因為
ko.virtualElements.allowedBindings.debug
標誌未設定為 true。
何時使用括號
沒有任何額外的外掛 ,KnockoutJS 將只能檢視 ViewModel 上可觀察的屬性的實時 View 更新 (常規 observable
,還有 computed
,pureComputed
,observableArray
等)。可以像這樣建立一個 observable:
var vm = { name: ko.observable("John") };
在這種情況下,vm.name
是一個具有兩個獨立模式 的函式 :
- Getter:
vm.name()
,沒有引數,將獲得當前值; - 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
有關更多詳細資訊,請參閱此問答 。