組件是一個(gè)強(qiáng)大的,干凈的方式組織您的UI代碼變成自包含,可重復(fù)使用的塊。 他們有以下的好處:
- 可以表示單獨(dú)的控件/窗口小部件,或應(yīng)用程序的整個(gè)部分
- 包含自己的視圖,通常(但可選)自己的viewmodel
- 可以通過AMD或其他模塊系統(tǒng)預(yù)加載或異步加載(按需)
- 可以接收參數(shù),并可選地將更改寫回到它們或調(diào)用回調(diào)
- 可以組合在一起(嵌套)或繼承自其他組件
- 可以輕松地打包,以便跨項(xiàng)目重用
- 讓你定義自己的約定/邏輯進(jìn)行配置和加載
此模式有利于大型應(yīng)用程序,因?yàn)樗ㄟ^明確的組織和封裝簡化了開發(fā),并通過根據(jù)需要增量式加載應(yīng)用程序代碼和模板來幫助提高運(yùn)行時(shí)性能。
自定義元素是用于消費(fèi)組件的可選但方便的語法。 不需要使用綁定注入組件的占位符<div>,您可以使用具有自定義元素名稱的更多自描述標(biāo)記(例如,<voting-button>或<product-editor>)。 Knockout小心確保兼容性,即使與舊的瀏覽器,如IE 6。
示例:喜歡/不喜歡小部件
可以使用ko.components.register注冊組件(技術(shù)上,注冊是可選的,但它是最簡單的入門方式)。 組件定義指定一個(gè)viewModel和模板。 例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>組件與自定義標(biāo)簽</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;
//注冊一個(gè)組件
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>
根據(jù)需要從外部文件加載類似/不喜歡小部件
在大多數(shù)應(yīng)用程序中,您需要將組件視圖模型和模板保留在外部文件中。 如果將Knockout配置為通過AMD模塊加載器(如require.js)提取它們,則可以預(yù)加載(可能捆綁/壓縮)或根據(jù)需要逐步加載。
ko.components.register('like-or-dislike', {
viewModel: { require: 'files/component-like-widget' },
template: { require: 'text!files/component-like-widget.html' }
});
為了這個(gè)工作,文件files / component-like-widget.js和files / component-like-widget.html需要存在。 檢查出來(并查看源代碼上的.html) - 正如你將看到的,這是更清潔和更方便,包括定義中的內(nèi)聯(lián)代碼。
此外,您需要引用一個(gè)合適的模塊加載器庫(例如require.js)或?qū)崿F(xiàn)一個(gè)知道如何抓取您的文件的自定義組件加載器。
總結(jié)
- 在knockout里viewmodel只能綁定到一個(gè)dom節(jié)點(diǎn)上,該節(jié)點(diǎn)本身或者節(jié)點(diǎn)的內(nèi)部子節(jié)點(diǎn)都不能再繼續(xù)綁定viewmodel,即,不能再繼續(xù)使用ko.applyBindings方法
- 按照上訴的理論,雖然不能再次綁定viewmodel,但是一個(gè)viewmodel里面是可以存在多個(gè)knockout組件,即 自定義標(biāo)簽。每個(gè)自定義標(biāo)簽也相當(dāng)于一個(gè)viewmodel,而且最外層根viewmodel可以通過參數(shù)的傳遞給各個(gè)自定義組件的viewmodel來達(dá)到相互綁定,改變UI的方法。