- KnockoutJS 教程
- KnockoutJS - 首頁
- KnockoutJS - 概述
- KnockoutJS - 環境搭建
- KnockoutJS - 應用
- KnockoutJS - MVVM 框架
- KnockoutJS - 可觀察物件
- 計算可觀察物件
- KnockoutJS - 宣告式繫結
- KnockoutJS - 依賴項跟蹤
- KnockoutJS - 模板
- KnockoutJS - 元件
- KnockoutJS 資源
- KnockoutJS - 快速指南
- KnockoutJS - 資源
- KnockoutJS - 討論
KnockoutJS - 元件繫結
此繫結用於將元件插入 DOM 元素並可選地傳遞引數。此繫結可以透過以下兩種方式實現:
- 簡寫語法
- 完整語法
簡寫語法
在這種方法中,只指定元件名稱,而不指定任何引數。
語法
<div data-bind = 'component: "component-name"'></div>
傳遞的引數值可以是可觀察物件。因此,每當可觀察物件發生變化時,舊的元件例項將被銷燬,並根據更新後的引數值建立新的元件例項。
完整語法
此方法以物件的格式接受引數。
語法
<div data-bind = 'component: {
name: "component-name",
params: { param1: value1, param2:value2 ...}
}'></div>
該物件由以下兩個專案組成:
name - 這是要插入的元件的名稱。如前所述,這可以是可觀察物件。
params - 這是要傳遞給元件的物件。大多數情況下,這將是一個包含多個引數的鍵值對物件。這通常由 ViewModel 的建構函式接收。
元件處理流程
下圖說明了透過元件繫結注入元件時發生的流程。
讓我們詳細瞭解一下這個過程:
從元件載入器接收 ViewModel 工廠和模板 - 預設載入器請求並接收已註冊的 ViewModel 和模板。預設情況下,這是一個非同步過程。
克隆元件模板 - 在此步驟中,克隆元件模板並將其插入 DOM 元素。如果存在任何現有內容,則將其刪除。
如果存在,則例項化 ViewModel - 在此步驟中,例項化 ViewModel。如果 ViewModel 以建構函式的形式提供,則 KO 呼叫。
new ViewModelName(params)
如果 ViewModel 以工廠函式格式提供,即 createViewModel,則 KO 呼叫。
createViewModel(params, yourcomponentInfo)
此處 yourcomponentInfo.element 是插入模板的元素。
將 ViewModel 繫結到檢視 - 在此階段,ViewModel 繫結到檢視。如果未提供 ViewModel,則使用元件繫結中提到的引數進行繫結。
元件現在已準備就緒 - 在此階段,元件已準備就緒並可以正常工作。元件會監控任何可觀察的引數,以便寫入更改的值。
如果元件丟失,則銷燬 ViewModel - 如果元件繫結的名稱值發生可觀察的變化,或者某些控制流繫結刪除了旨在容納元件輸出的 DOM 元素容器本身,則會呼叫 ViewModel 的銷燬函式。銷燬發生在任何元素容器從 DOM 中移除之前。
示例
讓我們來看一個演示元件繫結用法的示例。
<!DOCTYPE html>
<head>
<title>KnockoutJS Component binding</title>
<script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"
type = "text/javascript"></script>
</head>
<body>
<h4>Component binding without parameters</h4>
<div data-bind = 'component: "calculate-sum"'></div>
<h4>Component binding passing parameters</h4>
<div data-bind = 'component: {
name: "calculate-sum",
params: { number1: 2, number2: 3 }
}'></div>
<script>
ko.components.register('calculate-sum', {
viewModel: function(params) {
this.number1 = ko.observable(params && params.number1);
this.number2 = ko.observable(params && params.number2);
this.result = ko.computed(function() {
var sum = Number(this.number1()) + Number(this.number2());
if ( isNaN(sum) )
sum = 0;
return sum;
},this);
},
template: 'Enter Number One: <input data-bind = "value: number1" /> <br> <br>'+
' Enter Number Two: <input data-bind = "value: number2" /> <br> <br>'+
' Sum = <span data-bind = "text: result" />'
});
ko.applyBindings();
</script>
</body>
</html>
輸出
讓我們執行以下步驟來檢視上述程式碼的工作原理:
將上述程式碼儲存在 **component-bind.htm** 檔案中。
在瀏覽器中開啟此 HTML 檔案。
在兩個文字框中輸入數字,並觀察總和是如何計算的。
觀察結果
僅包含模板的元件
可以建立沒有 ViewModel 的元件。元件可以只包含如下所示的模板。
ko.components.register('my-component', {
template: '<div data-bind = "text: productName"></div>'
});
DOM 將如下所示:
<div data-bind = 'component: {
name: "my-component",
params: { productName: someProduct.name }
}'></div>
在沒有 DOM 容器元素的情況下使用元件繫結
可能存在無法將元件插入 DOM 元素的情況。仍然可以藉助基於如下所示註釋標籤的無容器語法執行必要的繫結。
<!--ko--> 和 <!--/ko--> 充當起始和結束標記,使其成為虛擬語法,並像真實的容器一樣繫結資料。
記憶體管理和銷燬
可以可選地將銷燬函式作為 ViewModel 的一部分新增。如果包含此函式,則每當元件丟失或容器元素本身被移除時,它都會被呼叫。最好使用銷燬函式來釋放不需要的物件佔用的資源,這些資源預設情況下不能被垃圾回收。以下是一些示例:
setInterval 方法將一直執行,直到明確清除。clearInterval (handle) 用於停止此過程。
需要明確銷燬 ko.computed 屬性。否則,它們可能仍然會繼續接收來自其底層可觀察物件的通知。可以使用純計算函式避免手動銷燬。
確保在訂閱上使用 dispose() 方法,否則它會一直觸發更改直到銷燬。
需要銷燬在 DOM 元素上建立並在 createViewModel 內部建立的自定義事件處理程式。