對於knockoutJS來說,模板綁定和Mapping插件綁定是十分重要的功能,雖然模板綁定在我工做中用的及其少,但模板綁定的重要性不可忽視,在其餘前端框架中,如Angular、Vue等等,模板存在的意義十分重要,Mapping插件使得咱們可以脫離手工綁定,及其方便咱們快速綁定達到預期效果。javascript
KnockoutJS模板綁定更多用法:https://knockoutjs.com/documentation/template-binding.htmlphp
在mvc的開發中,對於經常使用的一些獨立的Html,習慣將它變成分佈視圖或是視圖組件,以此來方便調用以及重用,同時也達到解耦效果,一樣在前端開發中,對於部分重用度很高、複雜度高的UI、嵌套UI等這些部分,咱們也能夠設計成模板。html
在knockoutJS中經過template綁定將模板綁定到預期DOM元素中,將模板所依賴的數據呈現。模板綁定對於構建嵌套結構的頁面十分方便,默認狀況, Knockout使用jquery.tmpl模板引擎,使用模板綁定時,需引用jquery.tmpl和jQuery框架,或者你也能夠集成其它的模板引擎(須要瞭解Knockout 內部知識)。前端
模板語法:java
具體瞭解模板語法能夠查看:http://www.php.cn/js-tutorial-383558.htmljquery
若是你僅僅是聲明的字符串,KO將會使用它做爲模板的ID去渲染。應用在模板上的數據是你當前的viewModel對象。git
一、構建一個簡單模板api
<hr /> <label>標準模板</label> <div data-bind="template: 'personTemplate'"></div> <script id='personTemplate' type='text/html'> ${ name } 是 ${ age } 歲 <button class="btn btn-primary" data-bind='click: makeOlder'>增加一歲</button> </script> @section Scripts{ <script type='text/javascript'> var viewModel = { name: ko.observable('刺客'), age: ko.observable(20), makeOlder: function () { viewModel.age(viewModel.age() + 1); } }; $(function () { ko.applyBindings(viewModel); }) </script> }
經過設計一個簡單的模板,在viewModel中的name或age發生改變後,Knockout將自動從新render模板。在該例子裏,每次點擊按鈕都會從新渲染該模板。數組
二、構建一個性能更好點的簡單模板前端框架
<br /><hr /> <label>加強版</label> <div data-bind="template: 'personAdvancedTemplate'"></div> <script id='personAdvancedTemplate' type='text/html'> <label data-bind="text:name()+'是'+age()+'歲'"></label> <button class="btn btn-primary" data-bind='click: makeOlder'>增加一歲</button> </script> @section Scripts{ <script type='text/javascript'> var viewModel = { name: ko.observable('刺客'), age: ko.observable(20), makeOlder: function () { viewModel.age(viewModel.age() + 1); } }; $(function () { ko.applyBindings(viewModel); }) </script> }
經過data-bind的形式將屬性綁定時,若是屬性改變了,將直接改變值,而無需從新渲染模板,這比經過${property}方式更加高效點,可是若是說模板內容較小較簡單,直接使用${property}這種方式也是可行的,浪費點性能,寫起來快捷方便。
三、嵌套模板
<br /><hr /> <label>嵌套模版</label> <div data-bind="template: 'firstPersonAdvancedTemplate'"></div> <script id='firstPersonAdvancedTemplate' type='text/html'> <label data-bind="text:name()+'是'+age()+'歲'"></label> <button class="btn btn-primary" data-bind='click: makeOlder'>增加一歲</button> <div style="border:1px dotted red;" data-bind="template: 'secondPersonAdvancedTemplate'"></div> </script> <script id='secondPersonAdvancedTemplate' type='text/html'> <label data-bind="text:name()+'是'+age()+'歲'"></label> <button class="btn btn-primary" data-bind='click: makeOlder'>增加一歲</button> </script> @section Scripts{ <script type='text/javascript'> var viewModel = { name: ko.observable('刺客'), age: ko.observable(20), makeOlder: function () { viewModel.age(viewModel.age() + 1); } }; $(function () { ko.applyBindings(viewModel); }) </script> }
效果:
嵌套模板是在一個模板的基礎上,在模板中繼續使用data-bind的形式利用template嵌套其餘模板,模板的從新渲染以就近原則爲主,最近的模板數據改變,只渲染最近的模板,對於全部的模板不進行從新渲染。
四、foreach模板
在模板中使用foreach完成相應的循環顯示時,有兩種方式,一種使用模板語法{{each personArray}}這種形式 ,可是這種在性能上不如直接使用data-bind的方式,所以我將直接使用data-bind完成foreach模板綁定,
<br /><hr /> <label>foreach模板</label> <ul data-bind="template: { name: 'dynastyForeachTemplate',foreach: dynastys,afterAdd:afterAddFunc,beforeRemove:beforeRemoveFunc }"></ul> <script id='dynastyForeachTemplate' type='text/html'> <li><label data-bind="text:dynastyName()+'是'+dynastyAge()+'年'"></label></li> </script> @section Scripts{ <script type='text/javascript'> function dynastyViewModel(name, age) { dynastyName = ko.observable(name); dynastyAge = ko.observable(age); } var viewModel = { dynastys: ko.observableArray([new dynastyViewModel("秦朝", 30)]), afterAddFunc: function () { console.log("afterAddFunc"); }, beforeRemoveFunc: function () { console.log("beforeRemoveFunc"); }, addDynasty: function () { console.log("addDynasty"); viewModel.dynastys.push(new dynastyViewModel("", 0)); }, deleteDynasty: function (dynasty) { console.log("deleteDynasty"); viewModel.dynastys.remove(dynasty); } }; $(function () { ko.applyBindings(viewModel); viewModel.dynastys.push(new dynastyViewModel("唐朝", 300)); viewModel.dynastys.push(new dynastyViewModel("宋朝", 300)); viewModel.dynastys.push(new dynastyViewModel("元代", 300)); }) </script> }
對於複雜的模板來說,須要循環使用如跟帖回帖操做,只有內容不一樣、時間不一樣等等,其餘html元素是同樣的,則使用這種方式能大幅提升開發效率。當增長一個Item到fo'reach關聯的數組集合中時,只會將Item部分進行模板的從新渲染,其他已有的部分不影響,
當刪除Item項時,模板不執行渲染,只是將Item從集合中移除。
五、table模板
<br /><hr /> <label>table模板</label> <table class="table table-bordered"> <thead> <tr> <th>朝代</th> <th>存活時間</th> <th></th> </tr> </thead> <tbody data-bind="template: { name: 'dynastyTableTemplate', foreach: dynastys,afterAdd:afterAddFunc,beforeRemove:beforeRemoveFunc }"></tbody> <tfoot> <tr> <td colspan="3" class="text-center"><button class="btn btn-primary" data-bind="click:addDynasty">增長朝代</button></td> </tr> </tfoot> </table> <script id='dynastyTableTemplate' type='text/html'> <tr> <td><input data-bind="value:dynastyName" /></td> <td><input data-bind="value:dynastyAge" /></td> <td><button class="btn btn-danger" data-bind="click:$root.deleteDynasty">刪除</button></td> </tr> </script> @section Scripts{ <script type='text/javascript'> function dynastyViewModel(name, age) { dynastyName = ko.observable(name); dynastyAge = ko.observable(age); } var viewModel = { dynastys: ko.observableArray([new dynastyViewModel("秦朝", 30)]), afterAddFunc: function () { console.log("afterAddFunc"); }, beforeRemoveFunc: function () { console.log("beforeRemoveFunc"); }, addDynasty: function () { console.log("addDynasty"); viewModel.dynastys.push(new dynastyViewModel("", 0)); }, deleteDynasty: function (dynasty) { console.log("deleteDynasty"); viewModel.dynastys.remove(dynasty); } }; $(function () { ko.applyBindings(viewModel); viewModel.dynastys.push(new dynastyViewModel("唐朝", 300)); viewModel.dynastys.push(new dynastyViewModel("宋朝", 300)); viewModel.dynastys.push(new dynastyViewModel("元代", 300)); }) </script> }
對於table模板的實際用法與foreach模板是同樣的,在foreach模板中也一樣能夠看見table模板的效果展現。
data-bind下template的綁定參數有
name(必選項) — 須要render的模板ID,能夠經過對綁定屬性中值的動態變換,切換不一樣的模板使用。
data(可選項) — 須要render到模板的數據。若是你忽略整個參數,KO將查找foreach參數,或者是應用整個view model對象。
foreach(可選項)— 指定KO按照「foreach」模式render模板
afterAdd或beforeRemove(可選項) — 在foreach模式下使用callback函數。
templateOptions(可選項) — 在渲染模板時可傳遞額外數據以便使用,可幫助你使用一些不屬於viewModel過濾條件或者字符來重用模板。
固然還有其餘模板引擎可使用,可是就目前來說,我的感受jquery.tmpl引擎已經知足個人需求了。
本文地址:http://www.javashuo.com/article/p-xsvtroit-dn.html
本文demo地址:https://gitee.com/530521314/koInstance.git
2018-10-13,望技術有成後能回來看見本身的腳步