【Knockout.js 學習體驗之旅】(3)模板綁定

来源:http://www.cnblogs.com/qieguo/archive/2016/06/14/5579888.html
-Advertisement-
Play Games

本文是【Knockout.js 學習體驗之旅】系列文章的第3篇,所有demo均基於目前knockout.js的最新版本(3.4.0)。小茄才識有限,文中若有不當之處,還望大家指出。 目錄: 【Knockout.js 學習體驗之旅】(1)ko初體驗 【Knockout.js 學習體驗之旅】(2)花式捆 ...


本文是【Knockout.js 學習體驗之旅】系列文章的第3篇,所有demo均基於目前knockout.js的最新版本(3.4.0)。小茄才識有限,文中若有不當之處,還望大家指出。

目錄:

      【Knockout.js 學習體驗之旅】(1)ko初體驗

        【Knockout.js 學習體驗之旅】(2)花式捆綁

        【Knockout.js 學習體驗之旅】(3)模板綁定

 

模板引擎

頁面是由數據和HTML組件構成的,如何將數據嵌入到HTML組件裡面呢?一個比較好的選擇是使用模板技術。

回顧下第一篇(【Knockoutjs 學習體驗之旅】(1)ko初體驗開頭的總價計算:

  1 <!--HTML Code-->
  2 <div class="counter">
  3     Price: <input type="text" data-bind="{value: price, valueUpdate: 'afterkeydown'}" placeholder="請輸入單價" /><br />
  4     Account: <input type="text" data-bind="textInput: account" placeholder="請輸入個數" /><br />
  5     sum: <span data-bind="text: sum"></span>
  6 </div>

這就是一個簡單的組件,他有自己的內部結構,有自己的事件處理機制。假如我需要使用很多個這樣的組件,那肯定不會是將上面的HTML代碼複製 n 遍插入到不同的地方吧,況且單純複製還不行,還要將變數區分開呢!如果是在一個列表裡面,那可以用 foreach 來做,如果是要用在不同的容器內,那就要使用模板引擎技術了。

模板技術並不是什麼高深的東西,有基於字元串拼接技術的,有基於 DOM 節點的,還有混合著的。更具體的介紹可以看一看這個輪子哥的文章 http://www.tuicool.com/articles/qMJ77r,樓主就不班門弄斧了。knockout.js 也是基於DOM節點的模板技術,編譯之後 view 與 data 還是保持綁定關係,可以簡單方便地更新數據到 view 層。另外你也可以將 knockout.js 鏈接到第三方的模板引擎,如 jquery.tmplUnderscore等模板引擎

下麵簡單講講ko中模板綁定的使用,第三方的集成引用不在本文討論範圍內。

knockout.js 的模板綁定

先看一個例子:

  1 <h2>Participants</h2> Here are the participants:
  2 <div data-bind="template: { name: 'person-template', data: buyer }"></div>
  3 <div data-bind="template: { name: 'person-template', data: seller }"></div>
  4 
  5 <!--模板-->
  6 <script type="text/html" id="person-template">
  7     <h3 data-bind="text: name"></h3>
  8     <p>Credits: <span data-bind="text: credits"></span></p>
  9 </script>
 10 
 11 <script type="text/javascript">
 12     function MyViewModel() {
 13         this.buyer = { name: 'Franklin', credits: 250 };
 14         this.seller = { name: 'Mario', credits: 5800 };
 15     }
 16     ko.applyBindings(new MyViewModel());
 17 </script>

<script type="text/html" id="person-template">這個script腳本標簽定義了一個 id 為"person-template"的模板,ko就是通過這個 id 來尋找相應的模板。註意這個腳本的 type 是"text/html",所以才能跟正常的腳本區分開。ko不會自動綁定在這種腳本內的代碼,只有在這個模板被使用的時候才會去綁定。

使用方法:HTML元素中使用 data-bind 綁定用到的模板,在 js 中定義相應的數據並應用該綁定。可以看到上面的"person-template"被引用了兩次,一次使用的是buyer的數據,另一次使用了seller數據。下麵簡單說說模板綁定中用到的參數:

  • name — 指定你要渲染的模板片段,跟模板腳本中的 id 相對應。
  • nodes — 直接傳遞一個DOM節點數組作為模板使用。傳遞的DOM節點數列應該是不被監控的,因為渲染過程中會對這個節點數列進行複製賦值等操作。而且如果這個節點數組有父級節點的話也會被移除。當我們傳遞了一個非空的name值時,nodes選項會被忽略,所以很少會用到這個屬性。
  • data — 用來作為渲染數據的對象。如果你忽略整個參數,KO將查找foreach參數,或者是應用整個view model對象。
  • if — 與上一篇中的 if 作用類似,只有當 if 後的表達式為真時才會渲染模板,用於防止一個空可觀察對象在模板被填充之前被綁定。
  • foreach — 按照“foreach”模式渲染模板。
  • as — 結合foreach使用的時候,指定每項渲染數據的別名,主要是用於定義數據範圍方便在嵌套綁定裡面使用。
  • afterRender, afterAdd, or beforeRemove — 渲染時的回調函數。

下麵簡單簡單介紹一下幾種用法。

一些例子

  • 使用 foreach 渲染 ViewModel中的所有數據
  1 <h2>Participants</h2>
  2 Here are the participants:
  3 <div data-bind="template: { name: 'person-template', foreach: people }"></div>
  4 
  5 <script type="text/html" id="person-template">
  6     <h3 data-bind="text: name"></h3>
  7     <p>Credits: <span data-bind="text: credits"></span></p>
  8 </script>
  9 
 10  function MyViewModel() {
 11      this.people = [
 12          { name: 'Franklin', credits: 250 },
 13          { name: 'Mario', credits: 5800 }
 14      ]
 15  }
 16  ko.applyBindings(new MyViewModel());

這個例子跟上面的例子效果是一樣的,使用 foreach 會將所有數據都渲染到模板中。區別就在於HTML的層級,使用data指定的時候,每一份數據渲染到對應的容器中;使用foreach的時候所有數據都被綁定到了一個容器內。上一篇中也介紹了foreach的用法,用不用模板都能得到一樣的效果。回憶一下foreach的寫法:

  1 <div data-bind="foreach: people">
  2     <h3 data-bind="text: name"></h3>
  3     <p>Credits: <span data-bind="text: credits"></span></p>
  4 </div>
  • as 在嵌套綁定中的使用
  1 <ul data-bind="template: { name: 'seasonTemplate', foreach: seasons, as: 'season' }"></ul>
  2 
  3 <script type="text/html" id="seasonTemplate">
  4     <li>
  5         <strong data-bind="text: name"></strong>
  6         <ul data-bind="template: { name: 'monthTemplate', foreach: months, as: 'month' }"></ul>
  7     </li>
  8 </script>
  9 
 10 <script type="text/html" id="monthTemplate">
 11     <li>
 12         <span data-bind="text: month"></span>
 13         is in
 14         <span data-bind="text: season.name"></span>
 15     </li>
 16 </script>
 17 
 18 <script>
 19     var viewModel = {
 20         seasons: ko.observableArray([
 21             { name: 'Spring', months: [ 'March', 'April', 'May' ] },
 22             { name: 'Summer', months: [ 'June', 'July', 'August' ] },
 23             { name: 'Autumn', months: [ 'September', 'October', 'November' ] },
 24             { name: 'Winter', months: [ 'December', 'January', 'February' ] }
 25         ])
 26     };
 27     ko.applyBindings(viewModel);
 28 </script>

上面這種多層的綁定中,要在下級綁定層次中要引用上層的話,就可以使用 as 定義的別名了。當然層次簡單的時候,用$parent也是可以的,用 as 會更加清晰,不會糾結在層次關係中。

註意:as 後接的別名應該用引號引起來,因為這裡我們是命名一個變數,而不是讀取一個已經存在的變數。

  • 動態決定使用哪個模板
  1 <ul data-bind='template: { name: displayMode, foreach: employees }'> </ul>
  2 <script id="active" type='text/html'>
  3     <li><span data-bind='text: name'></span>uses the "active" template!</li>
  4 </script>
  5 <script id="inactive" type='text/html'>
  6     <li><span data-bind='text: name'></span>uses the "inactive" template!</li>
  7 </script>
  8 
  9 <script>
 10     var viewModel = {
 11         employees: ko.observableArray([{
 12             name: "Kari",
 13             active: ko.observable(true)
 14         }, {
 15             name: "Brynn",
 16             active: ko.observable(false)
 17         }, {
 18             name: "Nora",
 19             active: ko.observable(false)
 20         }]),
 21         displayMode: function(employee) {
 22             // Initially "Kari" uses the "active" template, while the others use "inactive"
 23             return employee.active() ? "active" : "inactive";
 24         }
 25     };
 26     // ... then later ...
 27     viewModel.employees()[1].active(true);
 28     // Now "Brynn" is also rendered using the "active" template.
 29     ko.applyBindings(viewModel);
 30 </script>

上面這個例子有 active 和 inactive 兩個模板,ul 元素的 name 沒有直接指定模板 id ,而是通過一個函數返回模板 id,達到了選擇不同模板的目的。

吐槽一下:官方的文檔相當省,模板腳本都省掉了。。。博客園的湯姆大叔,居然也就那樣搬下來了,純翻譯的讓人無語。

Mapping插件

模板技術可以簡單地將數據和表現分離,採用前端渲染技術時,後臺只要將模型數據發給客戶端即可,前端將獲取到的數據渲染輸出。目前為止都是手動將獲取到的數據寫入 ViewModel 中,而 Mapping 插件就是幫你自動完成創建 ViewModel 的好工具。對比一下手動創建和使用 Mapping 插件兩種方式:

手動創建:

  1 // setup
  2 var viewModel = {
  3     serverTime: ko.observable(),
  4     numUsers: ko.observable()
  5 }
  6 // update:
  7 var data = getDataUsingAjax();  // your method to get data from server
  8 viewModel.serverTime(data.serverTime);
  9 viewModel.numUsers(data.numUsers);

Mapping插件

  1 var data = getDataUsingAjax();  // your method to get data from server
  2 var viewModel = ko.mapping.fromJS(data);
  3 ko.mapping.fromJS(data, viewModel);

假如從伺服器中獲取的數據比較多的話,使用Mapping的確可以減少很多代碼量。使用Mapping之後,data對象的所有屬性都被設置成可觀察對象,所有數組都被設置成可觀察對象數組,數組中的順序依然被保存。改變data對象的屬性或者增減數組項目就可以引起綁定更新事件。Mapping插件還有很多高級用法,不過除非非Mapping插件不可的情況,沒必要對一個插件投入太多精力去學習,搞太多還不如手寫算了。

總結

本篇主要簡單介紹了knockoutjs中模板技術的使用,感覺 ko 中用到的技術應該也差不多就這些了,自定義綁定和組件綁定相關的內容暫時沒有用到就不去深究了。組件的寫法有很多種,不一定要用 ko 的組件封裝規則,各有所好。 下一篇將會用一個綜合實例來介紹 ko 的各種綁定用法,敬請期待~~

碼字不易,隨手點贊哈~~~

 

參考資料:

  1. 官方教程: http://knockoutjs.com/documentation/introduction.html
  2. 湯姆大叔教程(官方教程翻譯,版本太舊,信息缺失明顯): http://www.cnblogs.com/TomXu/archive/2011/11/21/2257154.html
  3. 一個對前端模板技術的全面總結: http://www.tuicool.com/articles/qMJ77r

文字較多,慣例湊圖!

tibet-lake

(圖片來源:網路)

原創文章,轉載請註明出處!本文鏈接:http://www.cnblogs.com/qieguo/p/5579888.html  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文內容主要總結自《Java併發編程的藝術》第5章——Java中的鎖。 一、AQS AbstractQueuedSynchronizer(簡稱AQS),隊列同步器,是用來構建鎖或者其他同步組建的基礎框架。該類主要包括: 1、模式,分為共用和獨占。 2、volatile int state,用來表示鎖 ...
  • 異常的練習: 老師用電腦上課。開始思考上課中出現的問題。比如問題是 電腦藍屏。 電腦冒煙。要對問題進行描述,封裝成對象。可是當冒煙發生後,出現講課進度無法繼續。出現了講師的問題:課時計劃無法完成。 運行結果: NoPlanException: 上課無法繼續,因為電腦冒煙了 class Teacher ...
  • C++的深拷貝和淺拷貝 淺拷貝也叫位拷貝(bitwise assignment),意思就是將一個對象的記憶體映像按位原封不動的複製給另一個對象。如果欄位是值類型的,則對該欄位執行逐位複製;如果欄位是引用類型,則複製引用但不複製引用的對象。 如果改變目標對象中引用型欄位的值他將反映在原是對象中,也就是說 ...
  • http://blog.csdn.net/csh624366188/article/details/7183872 http://www.cnblogs.com/zhhh/archive/2011/06/10/2077519.html 又看到有人在問三層架構和MVC的關係,感覺這種問題有點教條化了。 ...
  • 1.點擊桌面的我Windows 圖標,找打控制面板 2.進入控制面板主頁,選擇系統和安全,進入系統和安全 3.進入系統和安全主頁後選擇管理工具,點擊進入 4.進入管理工具後,選擇數據源,進行數據源的配置 5.打開頁面之後點擊添加 6.打開添加頁面,選擇SQL SEVER 然後選擇完成 7.完成後進入 ...
  • addEventListener 用於註冊事件處理程式,IE 中為 attachEvent,我們為什麼講 addEventListener 而不講 attachEvent 呢?一來 attachEvent 比較簡單,二來 addEventListener 才是 DOM 中的標準內容。 簡介 addE ...
  • 最近一段時間要畢業了,忙著找工作,見過不少筆試面試題,自己總結了一些加上網上找的一些整合了一下。答案暫時都東拼西湊出來了,但是還是先不發出來,一方面是答案並不是唯一的並且自己的答案不能保證對,另一方面希望看到本文的伙伴能自己去找答案,畢竟,技術只有自己真正理解了才是自己的東西,共勉。 小白第一次發文 ...
  • js獲取url中的參數 function UrlSearch() { var name, value; var str = location.href; //取得整個地址欄 var num = str.indexOf("?") str = str.substr(num + 1); //取得所有參數 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...