組件是一個強大的,干凈的方式組織您的UI代碼變成自包含,可重復使用的塊。 他們有以下的好處:
- 可以表示單獨的控件/窗口小部件,或應用程序的整個部分
- 包含自己的視圖,通常(但可選)自己的viewmodel
- 可以通過AMD或其他模塊系統預加載或異步加載(按需)
- 可以接收參數,并可選地將更改寫回到它們或調用回調
- 可以組合在一起(嵌套)或繼承自其他組件
- 可以輕松地打包,以便跨項目重用
- 讓你定義自己的約定/邏輯進行配置和加載
此模式有利于大型應用程序,因為它通過明確的組織和封裝簡化了開發,并通過根據需要增量式加載應用程序代碼和模板來幫助提高運行時性能。
自定義元素是用于消費組件的可選但方便的語法。 不需要使用綁定注入組件的占位符<div>,您可以使用具有自定義元素名稱的更多自描述標記(例如,<voting-button>或<product-editor>)。 Knockout小心確保兼容性,即使與舊的瀏覽器,如IE 6。
示例:喜歡/不喜歡小部件
可以使用ko.components.register注冊組件(技術上,注冊是可選的,但它是最簡單的入門方式)。 組件定義指定一個viewModel和模板。 例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>組件與自定義標簽</title>
<script type="text/javascript" src="js/jquery-1.11.3.js"></script>
<script type="text/javascript" src="js/knockout.3.4.1.js"></script>
</head>
<body>
<div id="test">
<div data-bind='component: {
name: "like-widget",
params: { value: like }
}'></div>
</div>
<script type="text/javascript">
ko.ob = ko.observable;
ko.oba = ko.observableArray;
//注冊一個組件
ko.components.register('like-widget', {
template:
'<div class="like-or-dislike" data-bind="visible: !chosenValue()">\
<button data-bind="click: like">Like it</button>\
<button data-bind="click: dislike">Dislike it</button>\
</div>\
<div class="result" data-bind="visible: chosenValue">\
You <strong data-bind="text: chosenValue"></strong> it\
</div>'
,viewModel: function(params) {
var _this = this;
this.chosenValue = params.value;
_this.like = function() {
_this.chosenValue('like');
}
_this.dislike = function() {
this.chosenValue('dislike');
}.bind(_this);
}
});
var vm = {
like:ko.ob(false)
}
ko.applyBindings(vm,$("#test").get(0));
</script>
</body>
</html>
根據需要從外部文件加載類似/不喜歡小部件
在大多數應用程序中,您需要將組件視圖模型和模板保留在外部文件中。 如果將Knockout配置為通過AMD模塊加載器(如require.js)提取它們,則可以預加載(可能捆綁/壓縮)或根據需要逐步加載。
ko.components.register('like-or-dislike', {
viewModel: { require: 'files/component-like-widget' },
template: { require: 'text!files/component-like-widget.html' }
});
為了這個工作,文件files / component-like-widget.js和files / component-like-widget.html需要存在。 檢查出來(并查看源代碼上的.html) - 正如你將看到的,這是更清潔和更方便,包括定義中的內聯代碼。
此外,您需要引用一個合適的模塊加載器庫(例如require.js)或實現一個知道如何抓取您的文件的自定義組件加載器。
總結
- 在knockout里viewmodel只能綁定到一個dom節點上,該節點本身或者節點的內部子節點都不能再繼續綁定viewmodel,即,不能再繼續使用ko.applyBindings方法
- 按照上訴的理論,雖然不能再次綁定viewmodel,但是一個viewmodel里面是可以存在多個knockout組件,即 自定義標簽。每個自定義標簽也相當于一個viewmodel,而且最外層根viewmodel可以通過參數的傳遞給各個自定義組件的viewmodel來達到相互綁定,改變UI的方法。