对于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,望技术有成后能回来看见本身的脚步