knockout.js
knockout.js
0.双向绑定
<!DOCTYPE html> <html> <head> <title></title> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <!--step3: 绑定ViewModel到特定的View上--> My Name is <div id="div1" data-bind="text:personName"></div>, My Age is <strong data-bind="text:personAge"></strong> <p/> Name:<input type="text" data-bind="value:personName"/> Age:<input type="text" data-bind="value:personAge"/> <button onclick="changeName()">ChangeName</button> <button onclick="changeAge()">ChangeAge</button> <button onclick="test()">Test</button> <button onclick="getValue()">GetValue</button> </body> <script type="text/javascript"> //step2 定义ViewModel //var myViewModel ={personName:"zhangsan",personAge:18}; var myViewModel ={ personName:ko.observable(""), personAge:ko.observable() } //step4: 激活KO ko.applyBindings(myViewModel); function changeName(){ myViewModel.personName("zhangsan");//设置ViewModel的属性的值 } function changeAge(){ myViewModel.personAge(18); } function test(){ myViewModel.personName("lishi").personAge(20);//设置ViewModel的属性的值 } function getValue(){ var personName = myViewModel.personName();//获取ViewModel的值 var personAge=myViewModel.personAge(); alert("personName:"+personName+",personAge:"+personAge); } </script> </html>
1.创建数据模型和监控属性
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8" /> <script type="application/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <h1>姓名:<strong data-bind="text:personName"></strong></h1> <h2>年龄:<strong data-bind="text:personAge"></strong></h2> <input id="txtName" type="text" data-bind="value:personName"> <input id="txAge" type="text" data-bind="value:personAge" /> <br /> <button onclick="cancelSubscribe()">取消订阅</button> <script> var subscription=null; var ViewModel1={ personName:ko.observable("123"),//KO的双向绑定 personAge:ko.observable()// }; ko.applyBindings(ViewModel1);//激活KO //开启订阅 subscription=ViewModel1.personAge.subscribe(function (newValue) { if(isNaN(newValue)){ alert("请输入数字!"); ViewModel1.personAge(""); } }); function cancelSubscribe() { if (subscription) { subscription.dispose();//取消订阅 } } </script> </body> </html>
2.自动计算属性
2.1 Computed Observable
<!DOCTYPE html> <html lang="en"> <head> <title>Title</title> <meta charset="UTF-8"> <script type="application/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> firstName is <span data-bind="text:firstName"></span><br/> lastName is <span data-bind="text:lastName"></span><br /> fullName is <span data-bind="text:fullName"></span><br/> <input type="text" data-bind="value:firstName" /><br/> <input type="text" data-bind="value:lastName" /><br /> <script type="application/javascript"> function viewModel() { var self =this; self.firstName = ko.observable(""); self.lastName =ko.observable(""); //this关键字 计算属性 self.fullName = ko.computed(function () { return self.firstName()+'.'+self.lastName(); },self); } ko.applyBindings(viewModel); </script> </body> </html>
2.2 分解用户输入
<!DOCTYPE html> <html lang="en"> <head> <title>分解用户输入</title> <meta charset="UTF-8"> <script type="application/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> firstName is <span data-bind="text:firstName"></span><br/> lastName is <span data-bind="text:lastName"></span><br /> fullName is <span data-bind="text:fullName"></span><br/> <input type="text" data-bind="value:firstName" /><br/> <input type="text" data-bind="value:lastName" /><br /> <input type="text" data-bind="value:fullName" /> <script type="application/javascript"> function ViewModel() { var self =this; self.firstName = ko.observable(""); self.lastName =ko.observable(""); self.fullName=ko.computed({ read: function () { //读取 显示 return this.firstName() + " " + this.lastName(); }, write:function (value) { //输入的操作 var lastSpacePos = value.lastIndexOf(" "); if(lastSpacePos>0){ this.firstName(value.substring(0, lastSpacePos)); this.lastName(value.substring(lastSpacePos + 1)); } }, owner:self }); } ko.applyBindings(ViewModel); </script> </body> </html>
2.3 值的转换(value 转换)
<!DOCTYPE html> <html lang="en"> <head> <title>value值转换</title> <meta charset="UTF-8"> <script type="application/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> 数字是 <span data-bind="text:price "></span><br/> 价格是 <input type="text" data-bind="value:formattedPrice" /><br/> <script> function viewModel() { var self=this; self.price = ko.observable(12.445); self.formattedPrice=ko.computed({ read:function () { return '$' + self.price().toFixed(2);// }, write:function (value) { value = parseFloat(value.replace(/[^\.\d]/g, ""));// self.price(isNaN(value) ? 0 : value);// }, owner:self }); } ko.applyBindings(viewModel); </script> </body> </html>
2.4 筛选和验证用户输入
<!DOCTYPE html> <html lang="en"> <head> <title>筛选和验证用户输入</title> <meta charset="UTF-8"> <script type="application/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> 请输入新的价格:<input id="txtNumber" type="text" data-bind="value:attemptedValue"/> <div data-bind="visible:!lastInputWasValid()"> <font color="red">请输入数字!</font> </div> <script> function MyViewModel() { this.acceptedNumericValue = ko.observable(123); this.lastInputWasValid = ko.observable(true);//控制显示 true/false this.attemptedValue = ko.computed({//输入的值 read: this.acceptedNumericValue, write: function (value) { if (isNaN(value)) this.lastInputWasValid(false); else { this.lastInputWasValid(true); this.acceptedNumericValue(value); } }, owner: this }); } ko.applyBindings(new MyViewModel()); </script> </body> </html>
3.监控数组 observableArray
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> Country:<select data-bind="options:availableCountries"></select> <button onclick="add()">添加</button> <button onclick="del() ">删除</button> <button onclick="edit()">修改</button> <button onclick="index()">IndexOf</button> <button onclick="slice()">slice</button> <button onclick="unshift()">unshift</button> </body> <script type="text/javascript"> //myObservableArray.push('Some new value'):增加一个新的元素 // myObservableArray.pop():删除一个元素,并返回其值 // myObservableArray.unshift('Some new value'):在数组的开始处增加一个新的元素 // myObservableArray.shift():删除数组的第一个元素,并返回其值 // myObservableArray.reverse():反转数组的顺序 // myObservableArray.sort():数组排序。 var viewModel = { availableCountries : ko.observableArray(['France', 'Germany', 'Spain']) // These are the initial options }; ko.applyBindings(viewModel); function add(){ //viewModel.availableCountries().push("England"); viewModel.availableCountries.push("England"); } function del(){ // viewModel.availableCountries.shift(); // viewModel.availableCountries.pop(); //viewModel.availableCountries.remove("Germany"); //viewModel.availableCountries.removeAll(["France","Spain"]); /*var result = viewModel.availableCountries.remove(function(item){ return item.length>5; }); console.log(result);*/ var result = viewModel.availableCountries.splice(1,2);//删除 ,从索引1开始删除2个元素! console.log(result); } function edit(){ //viewModel.availableCountries[0]="aaaa"; viewModel.availableCountries.replace("Germany","china"); } function index(){ var index = viewModel.availableCountries.indexOf("Germany"); alert(index); var item = viewModel.availableCountries()[index]; alert(item); } function slice(){ var result = viewModel.availableCountries.slice(1,3); console.log(result); } function unshift(){ viewModel.availableCountries.unshift("--selected--");// } </script> </html>
4.使用内置绑定
4.1 控制文本和外观
visible
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="visible:isShow"> Hello,Knockout.js </div> <button onclick="show()">show</button> <button onclick="hide()">hide</button> </body> <script type="text/javascript"> function MyViewMode(){ this.isShow=ko.observable(true); } var myViewModel = new MyViewMode() ko.applyBindings(myViewModel); function show(){ myViewModel.isShow(true); } function hide(){ myViewModel.isShow(false); } </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="visible:myValues().length>0"> Hello,Knockout.js </div> <button onclick="add()">Add</button> <button onclick="del()">Remove</button> </body> <script type="text/javascript"> var myViewModel={ myValues: ko.observableArray([]) }; ko.applyBindings(myViewModel); function add(){ myViewModel.myValues.push("aaa"); } function del(){ myViewModel.myValues.shift(); } </script> </html>
text
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="text:message"></div> <input type="text" data-bind="value:message"/> <button onclick="msg()">添加一段话</button> </body> <script type="text/javascript"> var myViewModel={ message:ko.observable("") }; ko.applyBindings(myViewModel); function msg(){ myViewModel.message("hello,knockout.js"); } </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="text:priceRating"></div> <div data-bind="text:price()>50?'high':'lower'"></div> <input type="text" data-bind="value:price" /> </body> <script type="text/javascript"> var myViewModel={ price:ko.observable(30) }; myViewModel.priceRating = ko.computed( function(){ return this.price()>50?"high":"lower"; }, myViewModel ); ko.applyBindings(myViewModel); </script> </html>
html
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="html:detail"></div> <div data-bind="text:detail"></div> </body> <script type="text/javascript"> var myViewModel={ detail:ko.observable() }; ko.applyBindings(myViewModel); myViewModel.detail("<script type='text/javascript'>alert('ok')"+"</"+"script><em>"+"For further details, " + "view the report<a href='report.html'>here</a>.</em>"); </script> </html>
css 控制class样式
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> <style type="text/css"> .profitWarning { color: red; } .font-w{ font-weight: bold; } </style> </head> <body> <div data-bind='text:detail,css:{profitWarning:currentProfit()<0,"font-w":currentProfit()>0}'></div> <input type="text" data-bind="value:currentProfit" /> <!--<div class="profitWarning">Hello,Knockout.js</div>--> </body> <script type="text/javascript"> var myViewModel={ detail:ko.observable(), currentProfit: ko.observable(15000) }; ko.applyBindings(myViewModel); myViewModel.detail("Hello , Knockout.js"); myViewModel.currentProfit(-1); </script> </html>
style 样式
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <input type="text" data-bind="value:price,style:{color:price()>0?'red':'black'}"/> <!--<span data-bind="style:{color:price()>0?'red':'black','font-Weight':price()>0?'bold':'normal'}">测试</span>--> <span data-bind="style:{color:price()>0?'red':'black',fontWeight:price()>0?'bold':'normal'}">测试</span> </body> <script type="text/javascript"> var myViewMode = { price:ko.observable(100) } ko.applyBindings(myViewMode); </script> </html>
attr
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <a data-bind="text:content,attr:{href:url,title:title,target:desc}"></a> </body> <script type="text/javascript"> var myViewMode = { url:ko.observable("http://www.baidu.com"), title:ko.observable("点击打开百度"), desc:"_blank", content:"百度" } ko.applyBindings(myViewMode); </script> </html>
4.2 绑定逻辑控制
foreach
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <table border="1"> <thead><tr><th>First Name</th><th>Last Name</th></tr></thead> <tbody data-bind="foreach:people"> <tr> <td data-bind="text:firstName"></td> <td data-bind="text:lastName"></td> </tr> </tbody> </table> </body> <script type="text/javascript"> ko.applyBindings({ people:[ { firstName: 'Bert', lastName: 'Bertington' }, { firstName: 'Charles', lastName: 'Charlesforth' }, { firstName: 'Denise', lastName: 'Dentiste' } ] }); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <h4>People</h4> <ul data-bind="foreach:people"> <li> Name:<span data-bind="text:name"></span> <a href="#" data-bind="click:$parent.removePerson">Remove</a> </li> </ul> <button data-bind="click:addPerson">Add</button> </body> <script type="text/javascript"> function AppViewModel(){ var self = this; self.people=ko.observableArray([ {name:"zhang"}, {name:"wang"}, {name:"li"} ]); self.addPerson=function(){ self.people.push({name:"New at is "+new Date()}); }; self.removePerson = function(){ self.people.remove(this); } } ko.applyBindings(new AppViewModel()); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <h4>People</h4> <ul data-bind="foreach:people"> <li> Name:<span data-bind="text:$data.name"></span><!-- $data foreach中遍历的元素 --> <a href="#" data-bind="click:$parent.removePerson">Remove</a> </li> </ul> <button data-bind="click:addPerson">Add</button> <ul data-bind="foreach:month"> <li data-bind="text:$data"></li> </ul> </body> <script type="text/javascript"> function AppViewModel(){ var self = this; self.people=ko.observableArray([ {name:"zhang"}, {name:"wang"}, {name:"li"} ]); self.month=ko.observableArray([ 'Jan', 'Feb', 'Mar', 'etc' ]); self.addPerson=function(){ self.people.push({name:"New at is "+new Date()}); }; self.removePerson = function(){ self.people.remove(this); } } ko.applyBindings(new AppViewModel()); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <h1 data-bind="text:title"></h1> <ul data-bind="foreach:articles"> <li data-bind="text:name"></li> from <strong data-bind="text:$parent.title"></strong> </ul> </body> <script type="text/javascript"> function Article(){ this.title= ko.observable("Knockout.js从入门到精通"); this.articles = ko.observableArray([{name:"文章一"},{name:"文章二"},{name:"文章三"}]); } ko.applyBindings(new Article()); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <!--<ul data-bind="foreach:categories"> <li> <ul data-bind="foreach:items"> <li> <span data-bind="text:$parent.name"></span> <span data-bind="text:$data"></span> </li> </ul> </li> </ul>--> <ul data-bind="foreach:{data:categories,as:'c'}"> <li> <ul data-bind="foreach:{data:items,as:'item'}"> <li> <span data-bind="text:c.name"></span> <span data-bind="text:item"></span> </li> </ul> </li> </ul> </body> <script type="text/javascript"> var viewModel ={ categories:ko.observableArray([ {name:"A",items:["A1","A2","A3"]}, {name:"B",items:["B1","B2","B3"]} ]) }; ko.applyBindings(viewModel); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <ul> <li>商品类别如下:</li> <!-- ko foreach: items --> <li> <span data-bind="text:$index"></span> item <span data-bind="text:$data"></span> </li> <!-- /ko --> </ul> </body> <script type="text/javascript"> var viewModel ={ items:ko.observableArray(["A","B","C"]) }; ko.applyBindings(viewModel); </script> </html>
if / Ifnot
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <lable><input type="checkbox" data-bind="checked:displayMessage"/>Display Message</lable> <div data-bind="if:displayMessage">Here is A Message</div> <div data-bind="visible:displayMessage">Hello,Knockout.js</div> </body> <script type="text/javascript"> ko.applyBindings({ displayMessage:ko.observable(false) }) </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <ul data-bind="foreach:mydata"> <li> name:<b data-bind="text:name"></b> <div data-bind="if:code"> code:<b data-bind="text:code.child"></b> </div> </li> </ul> </body> <script type="text/javascript"> var viewModel ={ mydata:[ { name:"name01",code:null },{ name:"name02",code:{child:"mychild"} } ] } ko.applyBindings(viewModel); </script> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <lable><input type="checkbox" data-bind="checked:displayMessage"/>Display Message</lable> <div data-bind="ifnot:!displayMessage()">Here is A Message</div> </body> <script type="text/javascript"> ko.applyBindings({ displayMessage:ko.observable(true) }) </script> </html>
with
<!DOCTYPE html> <html> <head> <title></title> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <h1 data-bind="text:city"></h1> <!--<p> latitude:<span data-bind="text:coords.latitude"></span> <br/> longitude:<span data-bind="text:coords.longitude"></span> </p>--> <!--<p data-bind="with: coords">--> <p data-bind="with: coords"> latitude:<span data-bind="text: latitude"></span> <br/> longitude:<span data-bind="text: longitude"></span> </p> </body> <script type="text/javascript"> var viewModel ={ city: "London", coords: { latitude: 51.5001524, longitude: -0.1262362 } }; ko.applyBindings(viewModel); </script> </html>
5.模板绑定
5.1 jquery tmpl 模板
摘自:https://www.cnblogs.com/zhuzhiyuan/p/3510175.html
{{=}},{{tmpl}} and {{wrap}}.
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> <script type="text/javascript"> $(function(){ //第一种应用方式 /*var markup = "<li><b>${Name}</b>(${ReleaseYear})</li>"; $.template("movieTemplate",markup); var movies=[ {Name:"A电影",ReleaseYear:"1988"}, {Name:"B电影",ReleaseYear:"1998"}, {Name:"C电影",ReleaseYear:"2008"} ] $.tmpl("movieTemplate",movies).appendTo("#movieList");*/ //第二种应用方式 /*var markup = "<li><b>${Name}</b>(${ReleaseYear})</li>"; var movies=[ {Name:"A电影",ReleaseYear:"1988"}, {Name:"B电影",ReleaseYear:"1998"}, {Name:"C电影",ReleaseYear:"2008"} ] $.tmpl(markup,movies).appendTo("#movieList");*/ //第三种应用方式(推荐) var movies=[ {Name:"A电影",ReleaseYear:"1988"}, {Name:"B电影",ReleaseYear:"1998"}, {Name:"C电影",ReleaseYear:"2008"} ]; $("#movieTemplate").tmpl(movies).appendTo("#movieList"); }) </script> </head> <body> <ul id="movieList"></ul> <script id="movieTemplate" type="text/x-jquery-tmpl"> <li><b>${Name}</b>(${ReleaseYear})</li> </script> </body> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div1_demo"> </div> <script id="demo" type="text/x-jquery-tmpl"> <div style="margin-bottom:10px;"> <span>${ID}</span> <span style="margin-left:10px;">{{= Name}}</span> <span style="margin-left:10px;">${Number(Num)+1}</span> <span style="margin-left:10px;">${Status}</span> </div> </script> <script type="text/javascript"> var users = [ { ID: 'think8848', Name: 'Joseph Chan', Num: '1', Status: 1 }, { ID: 'aCloud', Name: 'Mary Cheung', Num: '2'} ]; $("#demo").tmpl(users).appendTo("#div1_demo"); </script> </body> </html>
{{each}}
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <h3>users</h3> <div id="div1_demo"></div> <!--<script id="demo" type="text/x-jquery-tmpl"> <ul> {{each users}} <li>Id:{{= $value.id}},Name:${$value.name}</li> {{/each}} </ul> </script>--> <script id="demo" type="text/x-jquery-tmpl"> <ul> {{each(index,item) users}} <li>No:${index},Id:{{= item.id}},Name:${item.name}</li> {{/each}} </ul> </script> <script type="text/javascript"> /*var users = [ { ID: 'think8848', Name: 'Joseph Chan', Num: '1', Status: 1 }, { ID: 'aCloud', Name: 'Mary Cheung', Num: '2'} ];*/ var data ={ users:[{id:1,name:"user01"},{id:2,name:"user02"},{id:3,name:"user03"}] }; $("#demo").tmpl(data).appendTo("#div1_demo"); </script> </body> </html>
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div_each"></div> <script id="each" type="text/x-jquery-tmpl"> <h3>users</h3> {{each(i,user) users}} <div>${i+1}:{{= user.name}}</div> {{if i==0}} <h4>group</h4> {{each(j,group) groups}} <div>${group.name}</div> {{/each}} {{/if}} {{/each}} <h3>depart</h3> {{each departs}} <div>{{= $value.name}}</div> {{/each}} </script> <script type="text/javascript"> /*var users = [ { ID: 'think8848', Name: 'Joseph Chan', Num: '1', Status: 1 }, { ID: 'aCloud', Name: 'Mary Cheung', Num: '2'} ];*/ var eachData = { users: [{ name: 'jerry' }, { name: 'john'}], groups: [{ name: 'mingdao' }, { name: 'meihua' }, { name: 'test'}], departs: [{ name: 'IT'}] }; $("#each").tmpl(eachData).appendTo("#div_each"); </script> </body> </html>
{{if }} {{else}}
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div_ifelse"> </div> <script id="ifelse" type="text/x-jquery-tmpl"> <div style="margin-bottom:10px;"> <p>ID:${ID}</p> <p>Name:{{= Name}}</p> <p>Other: {{if Status}} <span>${Status}</span> {{else App}} <span>${App}</span> {{else}} <span>None</span> {{/if}} </p> </div> </script> <script id="ifelseTo" type="text/x-jquery=tmpl"> <ul> {{each(index,item) users}} <li> index:${index},ID:${item.ID},Name:${item.Name} </li> {{/each}} </ul> </script> <script type="text/javascript"> var users = [ { ID: 'think8848', Name: 'Joseph Chan', Status: 1, App: 0 }, { ID: 'aCloud', Name: 'Mary Cheung', App: 1 }, { ID: 'bMingdao', Name: 'Jerry Jin'} ]; var data ={ users:[{id:1,name:"user01"},{id:2,name:"user02"},{id:3,name:"user03"}] }; //$("#ifelse").tmpl(users).appendTo("#div_ifelse"); // $("#demo").tmpl(data).appendTo("#div1_demo"); $("#ifelseTo").tmpl(data).appendTo("#div_ifelse"); </script> </body> </html>
{{html}} 输出变量html,但是没有html编码,适合输出html代码
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div_html"> </div> <script id="html" type="text/x-jquery-tmpl"> <div>Id:${Id}</div> <div>Name:{{= Name}}</div> <div>Html: ${html}, {{html html}} </div> </script> <script type="text/javascript"> var data = {Id:1,Name:"zhang",html:"<button>Test</button>"}; $("#html").tmpl(data).appendTo("#div_html"); </script> </body> </html>
{{tmpl}} 嵌套模版
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div_tmpl"></div> <script id="tmpl1" type="text/x-jquery-tmpl"> <h2>${ID}</h2> <p>Name:</p> {{tmpl($data) '#tmpl2'}} </script> <script id="tmpl2" type="text/x-jquery-tmpl"> <ul> {{each Name}} <li> ${$value} </li> {{/each}} </ul> </script> <script type="text/javascript"> var users = [ { ID: 'think8848', Name: ['Joseph', 'Chan'] }, { ID: 'aCloud', Name: ['Mary', 'Cheung']} ]; $("#tmpl1").tmpl(users).appendTo("#div_tmpl"); </script> </body> </html>
{{wrap}},包装器
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="div_wrap"> </div> <script id="tmpl1" type="text/x-jquery-tmpl"> The following wraps and reorders some HTML content: {{wrap "#tableWrapper"}} <h3>One</h3> <div> First <b>content</b> </div> <h3>Two</h3> <div> And <em>more</em> <b>content</b>... </div> {{/wrap}} </script> <script id="tableWrapper" type="text/x-jquery-tmpl"> <table cellspacing="0" cellpadding="3" border="1"><tbody> <tr> {{each $item.html("h3", true)}} <td> ${$value} </td> {{/each}} </tr> <tr> {{each $item.html("div")}} <td> {{html $value}} </td> {{/each}} </tr> </tbody></table> </script> <script type="text/javascript"> $('#tmpl1').tmpl().appendTo('#div_wrap'); </script> </body> </html>
$data $item $item代表当前的模板;$data代表当前的数据
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="mydiv"> </div> <script id="mytmpl" type="text/x-jquery-tmpl"> <div> <span>${$data.ID}</span> <span style="margin-left:10px">${$item.getName(" ")}</span> </div> </script> <script type="text/javascript"> var users = [ { ID: 'think8848', Name: ['Joseph', 'Chan'] }, { ID: 'aCloud', Name: ['Mary', 'Cheung']} ]; $("#mytmpl").tmpl(users,{ getName:function(spr){ return this.data.Name.join(spr); } }).appendTo("#mydiv"); </script> </body> </html>
$.tmplItem()方法,使用这个方法,可以获取从render出来的元素上重新获取$item
<!DOCTYPE html> <html> <head> <title></title> <meta charset="utf-8"/> <script type="text/javascript" src="js/jquery-1.6.4.js"></script> <script type="text/javascript" src="js/jquery-tmpl/jquery.tmpl.js"></script> </head> <body> <div id="mydiv"> </div> <script id="mytmpl" type="text/x-jquery-tmpl"> <div> <span>${$data.ID}</span> <span style="margin-left:10px">${$item.getName(" ")}</span> </div> </script> <script type="text/javascript"> var users = [ { ID: 'think8848', Name: ['Joseph', 'Chan'] }, { ID: 'aCloud', Name: ['Mary', 'Cheung']} ]; $("#mytmpl").tmpl(users,{ getName:function(spr){ return this.data.Name.join(spr); } }).appendTo("#mydiv"); $('#mydiv').delegate('div', 'click', function () { var item = $.tmplItem(this); alert(item.data.Name); }); </script> </body> </html>
5.2 KO模板绑定
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <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> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <!--<div data-bind="template:{name:'person-template',data:buyer}"></div> <div data-bind="template:{name:'person-template',data:seller}"></div>--> <div data-bind="template:{name:'person-template',foreach:person}"></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.person=[ { name: 'Franklin', credits: 250 }, { name: 'Mario', credits: 5800 } ] } ko.applyBindings(new MyViewModel()); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <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 data-bind="text:month"></li> is in <span data-bind="text:season.name"></span> </script> <script type="text/javascript"> 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> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <ul data-bind="template:{name:displayMode,foreach:employees}"></ul> <button onclick="test()">test</button> <script type="text/html" id="active"> <h3>A模板</h3> </script> <script type="text/html" id="inactive"> <h3>B模板</h3> </script> <script type="text/javascript"> function test(){ viewModel.employees()[1].active(true); } 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"; }}; ko.applyBindings(viewModel); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="../js/jquery-tmpl-master/jquery.tmpl.js"></script> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <!--<div data-bind="template:{name:'personTemplate'}"></div>--> <div data-bind="template:'personTemplate'"></div> <script type="text/html" id="personTemplate"> ${name} is ${age} yeas old <button data-bind="click:makeOlder">Make Older</button> </script> <script type="text/javascript"> var viewModel ={ name:ko.observable("zhangsan"), age:ko.observable(18), makeOlder:function(){ this.age(this.age()+1); } }; ko.applyBindings(viewModel); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="../js/jquery-tmpl-master/jquery.tmpl.js"></script> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <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:"zhang",age:12}, {name:"li",age:13}, {name:"wang",age:14} ] ) }; //ko.applyBindings(new viewModel()); ko.applyBindings(viewModel); </script> </body> </html>
6.KO高级篇
6.1 KO自定义绑定
你可以创建自己的自定义绑定 – 没有必要非要使用内嵌的绑定(像click,value等)。你可以你封装复杂的逻辑或行为,自定义很容易使用和重用的绑定。例如,你可以在form表单里自定义像grid,tabset等这样的绑定。
注册你的绑定
添加子属性到ko.bindingHandlers来注册你的绑定:
ko.bindingHandlers.yourBindingName = { init: function(element, valueAccessor, allBindingsAccessor, viewModel) { //此处当你定义的绑定被第一次应用于一个元素上时会被调用 //在这设置任意初始化程序、事件处理程序 }, update: function(element, valueAccessor, allBindingsAccessor, viewModel) { // This will be called once when the binding is first applied to an element, // and again whenever the associated observable changes value. // Update the DOM element based on the supplied values here. } };
然后就可以在任何DOM元素上使用了:
<div data-bind="yourBindingName: someValue"> </div>
注:你实际上没必要把init和update这两个callbacks都定义,你可以只定义其中的任意一个。
update 回调
当管理的observable改变的时候,KO会调用你的update callback函数,然后传递以下参数:
** element — 使用这个绑定的DOM元素
** valueAccessor —JavaScript函数,通过valueAccessor()可以得到应用到这个绑定的model上的当前属性值。
** allBindingsAccessor —JavaScript函数,通过allBindingsAccessor ()得到这个元素上所有model的属性值。
** viewModel — 传递给ko.applyBindings使用的 view model参数,如果是模板内部的话,那这个参数就是传递给该模板的数据。
例如,你可能想通过 visible绑定来控制一个元素的可见性,但是你想让该元素在隐藏或者显示的时候加入动画效果。那你可以自定义自己的绑定来调用jQuery的slideUp/slideDown 函数:
ko.bindingHandlers.slideVisible = { update: function(element, valueAccessor, allBindingsAccessor) { // First get the latest data that we're bound to var value = valueAccessor(), allBindings = allBindingsAccessor(); // Next, whether or not the supplied model property is observable, get its current value var valueUnwrapped = ko.utils.unwrapObservable(value); // Grab some more data from another binding property var duration = allBindings.slideDuration || 400; // 400ms is default duration unless otherwise specified // Now manipulate the DOM element if (valueUnwrapped == true) $(element).slideDown(duration); // Make the element visible else $(element).slideUp(duration); // Make the element invisible } };
然后你可以像这样使用你的绑定:
<div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div> <label><input type="checkbox" data-bind="checked: giftWrap"/> Gift wrap</label> <script type="text/javascript"> var viewModel = { giftWrap: ko.observable(true) }; ko.applyBindings(viewModel); </script>
当然,看来可能代码很多,但是一旦你创建了自定义绑定,你就可以在很多地方重用它。
init 回调
Knockout在DOM元素使用自定义绑定的时候会调用你的init函数。init有两个重要的用途:
** 为DOM元素设置初始值
** 注册事件句柄,例如当用户点击或者编辑DOM元素的时候,你可以改变相关的observable值的状态。
KO会传递和update回调函数一样的参数。
继续上面的例子,你可以像让slideVisible在页面第一次显示的时候设置该元素的状态(但是不使用任何动画效果),而只是让动画在以后改变的时候再执行。你可以这样来做:
ko.bindingHandlers.slideVisible = { init: function(element, valueAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()); // Get the current value of the current property we're bound to $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false }, update: function(element, valueAccessor, allBindingsAccessor) { // Leave as before } };
DOM事件之后更新observable值
你已经值得了如何使用update回调,当observable值改变的时候,你可以更新相关的DOM元素。但是其它形式的事件怎么做呢?比如当用户对某个DOM元素有某些action操作的时候,你想更新相关的observable值。
你可以使用init回调来注册一个事件句柄,这样可以改变相关的observable值,例如,
ko.bindingHandlers.hasFocus = { init: function (element, valueAccessor) { $(element).focus(function () { var value = valueAccessor(); value(true); } ); $(element).blur(function () { var value = valueAccessor(); value(false); }); }, update: function (element, valueAccessor) { var value = valueAccessor(); if (ko.utils.unwrapObservable(value)) element.focus(); else element.blur(); } };
现在你可以通过hasFocus绑定来读取或者写入这个observable值了:
<p>Name: <input data-bind="hasFocus: editingName"/></p> <!-- Showing that we can both read and write the focus state --> <div data-bind="visible: editingName">You're editing the name</div> <button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button> <script type="text/javascript"> var viewModel = { editingName: ko.observable() }; ko.applyBindings(viewModel); </script>
Demo
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="slideVisible:giftWrap,slideDuration:600">这是一个用于测试动画效果的DIV元素</div> <label><input type="checkbox" data-bind="checked:giftWrap">隐藏/显示 </label> <script type="text/javascript"> ko.bindingHandlers.slideVisible={ update: function(element, valueAccessor, allBindingsAccessor) { //第一步得到绑定元素上面的当前值 var value=valueAccessor(); var isVisible = ko.utils.unwrapObservable(value); //第二步得到所有data-bind所对应的属性 var allBindings = allBindingsAccessor(); var duration = allBindings.slideDuration || 400; console.log(isVisible); console.log(duration); //第三步根据当前绑定的值来做业务逻辑,当前值为true,就让当前的元素动画隐藏,否则的话,动画显示 if (isVisible){ $(element).slideDown(duration); }else{ $(element).slideUp(duration); } } }; var viewModel={ giftWrap: ko.observable(true) }; ko.applyBindings(viewModel); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <div data-bind="slideVisible:giftWrap,slideDuration:600">这是一个用于测试动画效果的DIV元素</div> <label><input type="checkbox" data-bind="checked:giftWrap">隐藏/显示 </label> <script type="text/javascript"> ko.bindingHandlers.slideVisible={ init:function(element, valueAccessor, allBindingsAccessor) { console.log("init"); var value = ko.utils.unwrapObservable(valueAccessor()); console.log("init value="+value); $(element).toggle(value); }, update: function(element, valueAccessor, allBindingsAccessor) { //第一步得到绑定元素上面的当前值 var value=valueAccessor(); var isVisible = ko.utils.unwrapObservable(value); //第二步得到所有data-bind所对应的属性 var allBindings = allBindingsAccessor(); var duration = allBindings.slideDuration || 400; console.log(isVisible); console.log(duration); //第三步根据当前绑定的值来做业务逻辑,当前值为true,就让当前的元素动画隐藏,否则的话,动画显示 if (isVisible){ $(element).slideDown(duration); }else{ $(element).slideUp(duration); } } }; var viewModel={ giftWrap: ko.observable(true) }; ko.applyBindings(viewModel); </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <!--step1:添加KO的引用--> <script type="text/javascript" src="../js/jquery-2.1.0.min.js"></script> <script type="text/javascript" src="../js/knockout-3.1.0.js"></script> </head> <body> <p>Name: <input data-bind="hasFocus: editingName"/></p> <p>Age:<input data-bind="hasFocus:editingName" /></p> <!-- Showing that we can both read and write the focus state --> <div data-bind="visible: editingName">You're editing the name</div> <button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button> <script type="text/javascript"> ko.bindingHandlers.hasFocus={ init:function(element, valueAccessor, allBindingsAccessor) { $(element).focus(function(){ var value=valueAccessor(); value(true);//viewModel.editingName(true) }); $(element).blur(function(){ var value = valueAccessor(); value(false);//viewModel.editingName(false) }) }, update: function(element, valueAccessor, allBindingsAccessor) { var value = ko.utils.unwrapObservable(valueAccessor()); if (value){ element.focus(); }else{ element.blur(); } } }; var viewModel={ editingName: ko.observable() }; ko.applyBindings(viewModel); </script> </body> </html>
6.2 控制子绑定