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 的建構函式接收。

元件處理流程

下圖說明了透過元件繫結注入元件時發生的流程。

component lifecycle

讓我們詳細瞭解一下這個過程:

從元件載入器接收 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 內部建立的自定義事件處理程式。

knockoutjs_declarative_bindings.htm
廣告
© . All rights reserved.