文章出處

目的

template綁定(模板綁定)使用渲染模板的結果填充關聯的DOM元素。 模板是一種簡單方便的方式來構建復雜的UI結構 。

下面介紹兩種使用模板綁定的方法:

  • 本地模板是支持foreach,if,with和其他控制流綁定的機制。 在內部,這些控制流綁定捕獲元素中包含的HTML標記,并將其用作模板以針對任意數據項進行呈現。 此功能內置在Knockout中,不需要任何外部庫。
  • 基于字符串的模板是一種將Knockout連接到第三方模板引擎的方法。 Knockout會將您的模型值傳遞給外部模板引擎,并將生成的標記字符串注入到文檔中。 請參閱下面的備注6使用jquery.tmpl和Underscore模板引擎的示例。

    參數

  • 快速語法:如果你只是提供一個字符串值,KO會將其解釋為要渲染的模板的ID。它提供給模板的數據將是您當前的模型對象。

  • 要獲得更多控件,請傳遞具有以下屬性的某些組合的JavaScript對象:

  • name — 包含要渲染的模板的元素的ID - 有關如何以編程方式更改此設置,請參見備注5。
  • nodes —直接傳遞DOM節點數組以用作模板。這應該是一個不可觀察的數組,并注意元素將從他們當前的父(如果他們有一個)中刪除。如果您還為name傳遞了一個非空值,則忽略此選項。
  • data — 要提供為要呈現的模板的數據的對象。如果省略此參數,KO將查找foreach參數,或者使用當前模型對象返回。
  • if — 如果提供此參數,那么只有在指定的表達式求值為true(或true-ish值)時,才會呈現模板。這可以有助于防止null observable在填充之前與模板綁定。
  • foreach — 指示KO以“foreach”模式渲染模板 - 有關詳細信息,請參見備注2。
  • as — 當與foreach結合使用時,為正在呈現的每個項目定義別名 - 有關詳細信息,請參見備注3。
  • afterRender, afterAddbeforeRemove — 要針對呈現的DOM元素調用的回調函數 - 請參閱備注4

    備注1:渲染命名模板

    通常,當您使用控制流綁定(foreach,with,if等)時,不需要給您的模板命名:它們是由DOM元素內的標記隱式和匿名定義的。 但是如果你想要,你可以將模板分解成一個單獨的元素,然后通過名稱引用它們:

    Participants

    Here are the participants:

    源碼:

    <h2>Participants</h2>
    Here are the participants:
    <div data-bind="template: { name: 'person-template', data: buyer }"></div>
    <div data-bind="template: { name: 'person-template', data: seller }"></div>
     
    <script type="text/html" id="person-template">
        <h3 data-bind="text: name"></h3>
        <p>Credits: <span data-bind="text: credits"></span></p>
    </script>
     
    <script type="text/javascript">
         function MyViewModel() {
             this.buyer = { name: 'Franklin', credits: 250 };
             this.seller = { name: 'Mario', credits: 5800 };
         }
         ko.applyBindings(new MyViewModel());
    </script>

    在此示例中,'person-template'標記使用兩次:一次用于買方,一次用于賣方。 請注意,模板標記被包裝在<script type =“text / html”>中 - 必須使用虛擬類型屬性,以確保標記不會作為JavaScript執行,Knockout不會嘗試對該標記應用綁定,除非 它被用作模板。

    使用命名模板不是經常被用到,但有時它可以幫助減少重復的標記。

    備注2:對命名模板使用“foreach”選項

    Participants

    Here are the participants:

    源碼:

    <h2>Participants</h2>
    Here are the participants:
    <div data-bind="template: { name: 'person-template', foreach: people }"></div>
     
    <script type="text/html" id="person-template">
        <h3 data-bind="text: name"></h3>
        <p>Credits: <span data-bind="text: credits"></span></p>
    </script>
     <script>
     function MyViewModel() {
         this.people = [
             { name: 'Franklin', credits: 250 },
             { name: 'Mario', credits: 5800 }
         ]
     }
     ko.applyBindings(new MyViewModel());
    </script>

    這給出了與在您使用foreach的元素內直接嵌入匿名模板相同的結果,例如:

    <div data-bind="foreach: people">
        <h3 data-bind="text: name"></h3>
        <p>Credits: <span data-bind="text: credits"></span></p>
    </div>

    備注3:使用“as”給“foreach”項目一個別名

    當嵌套foreach模板時,引用層次結構中較高級別的項目通常很有用。 一種方法是在綁定中引用$ parent或其他綁定上下文變量。

    然而,一個更簡單和更優雅的選項是使用as來為你的迭代變量聲明一個名字。 例如:

    <ul data-bind="template: { name: 'employeeTemplate',
                                      foreach: employees,
                                      as: 'employee' }"></ul>

    注意與as相關聯的字符串值“employee”。 現在在這個foreach循環中的任何地方,你的子模板中的綁定將能夠引用employee來訪問正在呈現的employee對象。

    如果你有多個嵌套的foreach塊,這是非常有用的,因為它給你一個明確的方法來引用層次結構中更高級別上聲明的任何命名項。 這是一個完整的例子,顯示季節可以在渲染一個月時被引用:

      源碼:

      <ul data-bind="template: { name: 'seasonTemplate', foreach: seasons, as: 'season' }"></ul>
       
      <script type="text/html" id="seasonTemplate">
          <li>
              <strong data-bind="text: name"></strong>
              <ul data-bind="template: { name: 'monthTemplate', foreach: months, as: 'month' }"></ul>
          </li>
      </script>
       
      <script type="text/html" id="monthTemplate">
          <li>
              <span data-bind="text: month"></span>
              is in
              <span data-bind="text: season.name"></span>
          </li>
      </script>
       
      <script>
          var viewModel = {
              seasons: ko.observableArray([
                  { name: 'Spring', months: [ 'March', 'April', 'May' ] },
                  { name: 'Summer', months: [ 'June', 'July', 'August' ] },
                  { name: 'Autumn', months: [ 'September', 'October', 'November' ] },
                  { name: 'Winter', months: [ 'December', 'January', 'February' ] }
              ])
          };
          ko.applyBindings(viewModel);
      </script>

      提示:請記住將字符串字面值傳遞為as(例如,as:'season',而不是as:season),因為您要出給一個新變量命名,而不是讀取已經存在的變量的值。

      備注4:使用afterRender, afterAdd,  beforeRemove

      有時,您可能希望對由模板生成的DOM元素運行自定義后處理邏輯。 例如,如果您使用JavaScript窗口部件庫(如jQuery UI),則可能需要攔截模板的輸出,以便可以對其運行jQuery UI命令,將一些渲染的元素轉換為日期選擇器,滑塊或別的什么東西。

      通常,對DOM元素執行此類后處理的最佳方法是編寫自定義綁定,但如果您只想訪問模板發出的原始DOM元素,則可以使用afterRender。

      傳遞函數引用(函數文字,或給出視圖模型上的函數名稱),Knockout將在渲染或重新渲染模板后立即調用它。 如果你使用foreach,Knockout將為添加到你的observable數組的每個項目調用你的afterRender回調函數。 例如,

      <div data-bind='template: { name: "personTemplate",
                                  data: myData,
                                  afterRender: myPostProcessingLogic }'> </div>

      并在視圖模型(即包含myData的對象)上定義相應的函數:

      viewModel.myPostProcessingLogic = function(elements) {
          // "elements" is an array of DOM nodes just rendered by the template
          // You can add custom post-processing logic here
      }

      如果您正在使用foreach,并且只希望通知有關特定要添加或正在刪除的元素,則可以使用afterAdd和beforeRemove。 有關詳細信息,請參閱第四章foreach綁定的文檔

      備注5:動態選擇使用哪個模板

      如果有多個命名模板,則可以為名稱選項傳遞observable。 隨著observable的值被更新,元素的內容將使用適當的模板重新渲染。 或者,您可以傳遞回調函數來確定要使用哪個模板。 如果您使用的是foreach模板模式,Knockout將評估數組中每個項目的函數,并將該項目的值作為唯一的參數。 否則,函數將給出數據選項的值,或者返回提供整個當前模型對象。

      源碼:

      <ul data-bind='template: { name: displayMode,
                                 foreach: employees }'> </ul>
       
      <script>
          var viewModel = {
              employees: ko.observableArray([
                  { name: "Kari", active: ko.observable(true) },
                  { name: "Brynn", active: ko.observable(false) },
                  { name: "Nora", active: ko.observable(false) }
              ]),
              displayMode: function(employee) {
                  // Initially "Kari" uses the "active" template, while the others use "inactive"
                  return employee.active() ? "active" : "inactive";
              }
          };
       
          // ... then later ...
          viewModel.employees()[1].active(true); // Now "Brynn" is also rendered using the "active" template.
      </script>

      如果你的函數引用了observable值,那么當這些值發生變化時,綁定就會更新。 這將導致使用適當的模板重新呈現數據。

      如果你的函數包含第二個參數,那么它將接收整個綁定上下文。 然后,當動態選擇模板時,可以訪問$ parent或任何其他綁定上下文變量。 例如,您可以修改上述代碼段,如下所示:

      displayMode: function(employee, bindingContext) {
          // Now return a template name string based on properties of employee or bindingContext
      }

      備注6:使用jQuery.tmpl,一個外部的基于字符串的模板引擎

      在絕大多數情況下,Knockout的本地模板和foreach,if,with和其他控制流綁定將需要構建一個任意復雜的UI。 但是,如果您希望與外部模板庫(例如Underscore模板引擎或jquery.tmpl)集成,Knockout提供了一種方法。

      默認情況下,Knockout支持jquery.tmpl。 要使用它,您需要按以下順序引用以下庫:

      <!-- First jQuery -->     <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
      <!-- Then jQuery.tmpl --> <script src="jquery.tmpl.js"></script>
      <!-- Then Knockout -->    <script src="knockout-x.y.z.js"></script>

      然后,您可以在模板中使用jQuery.tmpl語法。 例如

      <h1>People</h1>
      <div data-bind="template: 'peopleList'"></div>
       
      <script type="text/html" id="peopleList">
          {{each people}}
              <p>
                  <b>${name}</b> is ${age} years old
              </p>
          {{/each}}
      </script>
       
      <script type="text/javascript">
          var viewModel = {
              people: ko.observableArray([
                  { name: 'Rod', age: 123 },
                  { name: 'Jane', age: 125 },
              ])
          }
          ko.applyBindings(viewModel);
      </script>

      這是因為{{each ...}}和$ {...}是jQuery.tmpl語法。 更重要的是,嵌套模板很簡單:因為您可以在模板中使用數據綁定屬性,您可以簡單地在模板中放置一個data-bind =“template:...”來渲染嵌套的模板。

      請注意,截至2011年12月,jQuery.tmpl已不再處于積極開發階段。 我們建議使用Knockout的本地基于DOM的模板(即foreach,if,with等綁定),而不是jQuery.tmpl或任何其他基于字符串的模板引擎。


    • 文章列表




      Avast logo

      Avast 防毒軟體已檢查此封電子郵件的病毒。
      www.avast.com


      arrow
      arrow
        全站熱搜
        創作者介紹
        創作者 大師兄 的頭像
        大師兄

        IT工程師數位筆記本

        大師兄 發表在 痞客邦 留言(0) 人氣()