knockout已經使用一段時間了,但真正感受到一些東西了,仍是從下面這個例子開始的。不須要直接操做dom,有個綁定(固然是雙向的)便可,將數據和dom元素聯繫起來,免去了在定位dom。 javascript
一個tree樹的例子,帶有複選框、刪除節點及重命名功能。 css
效果圖: html
能夠從這裏查看 演示效果 java
Css代碼 bootstrap
<script type='text/javascript' src='http://www.see-source.com/js/knockout-2.2.0.js'></script> <style type="text/css"> li {list-style:none; font-size:14px;} ul {padding-left:25px;} .operaterDiv{width:100px; margin-left:100px;; z-index:100px;position:absolute;margin-top:-5px; border:1px solid #000;background-color:#FFF} .operaterDiv li{list-style-type:none; padding:1px; margin-left:20px;} .operaterDiv a:link {text-decoration: underline; color:blue;} .operaterDiv a:visited{text-decoration: underline;; color:blue;} .operaterDiv a:hover {text-decoration: none; color:blue;} .close{float:right; font-size:5px; color:red;} .highLight{background-color:#009; color:#FFF;} </style>Html代碼
<ul data-bind="template: { name: 'guideTmpl', foreach: menus}"></ul><br/> <a href="javascript:void(0)" onClick="getSelectedValues()">查看選中值</a><br/>Js代碼
<!--節點模板模板--> <script id="guideTmpl" type="text/html"> <li> <img data-bind="attr: {src:imageUrl}, click:$root.openOrClose"/> <input type="checkbox" data-bind="checked:selected"/> <span data-bind="text: name, visible:switchS, css:{highLight:editOpened}, event:{contextmenu:$root.myContextmenu, click:$root.openOrClose}, clickBubble: false"></span> <span data-bind="visible:!switchS()"><input type="text" data-bind="value:name,event:{blur:$root.closeAllOpenedDiv}"/></span> <div data-bind="visible: editOpened" class="operaterDiv"> <span class="close" data-bind="click:$root.closeOpenedDiv">關閉</span> <ul style="padding:0;margin:0; margin-top:5px;"> <li><a href="#" data-bind="click:function(){if(confirm('肯定要刪除嗎?')){$parent.children.remove(this)}; this.editOpened(false);}, clickBubble: false">Delete</a></li> <li><a href="#" data-bind="click:$root.doSwitch, clickBubble: false">Rename</a></li> </ul> </div> <ul data-bind="template: { name: 'guideTmpl', foreach: children }, visible:opened"></ul> </li> </script> <script type="text/javascript"> var index = 1;//用於模擬value值(實際中應是每一個節點的惟一標識) var Menu = function(name, children, opened, imageUrl, selected, value) {//節點對應的js對象 this.name = ko.observable(name); this.children = ko.observableArray(children || []); //下級子節點 this.opened = ko.observable(opened); //true:展開 false:摺疊 this.imageUrl = ko.observable("http://www.dhtmlgoodies.com/scripts/drag-drop-folder-tree/images/dhtmlgoodies_plus.gif"); //true:展開 false:摺疊 this.selected = ko.observable(false); this.value = "000" + index++; this.editOpened = ko.observable(false); this.switchS = ko.observable(true); }; var MenuModel = function() { var self = this; self.menus = ko.observableArray([ new Menu("Twitter BootStrap", [ new Menu("bootstrap介紹", [new Menu("2222")]), new Menu("響應式設計"), new Menu("JavaScript插件") ]), new Menu("Knockout", [ new Menu("監控屬性(Observables)"), new Menu("控制流綁定(Control flow)"), new Menu("表單域綁定(Form fields)"), new Menu("自定義綁定(Custom)") ]) ]); //展開、摺疊操做 self.openOrClose = function(source){ self.closeAllOpenedDiv(); var opened = source.opened(); if(source.children() == 0) return ; if(opened){ source.opened(false); source.imageUrl("http://www.dhtmlgoodies.com/scripts/drag-drop-folder-tree/images/dhtmlgoodies_plus.gif"); }else{ source.opened(true); source.imageUrl("http://www.dhtmlgoodies.com/scripts/drag-drop-folder-tree/images/dhtmlgoodies_minus.gif"); } var children = source.children(); for (var i in children){ if(children[i].children().length == 0 ){//存在子節 children[i].imageUrl("http://www.see-source.com/images/dhtmlgoodies_white.gif"); } } }; //得到複選框全部選中的value值 self.selectedValues = function(){ var valuesStr = ""; var menus = self.menus(); for (var i in menus){ if(menus[i].selected()){ valuesStr += ","; valuesStr += menus[i].value; } var qiantao = function(child){ for (var i in child){ if(child[i].selected()){ valuesStr += ","; valuesStr += child[i].value; } qiantao(child[i].children()); } } qiantao(menus[i].children()); } return valuesStr; }; //右鍵事件(彈出操做層) self.myContextmenu = function(source){ self.closeAllOpenedDiv(); source.editOpened(true); }; //切換 self.doSwitch = function(source){ source.switchS(false); source.editOpened(false); }; //關閉全部彈出操做層 self.closeAllOpenedDiv = function(){ var menus = self.menus(); for (var i in menus){ var qiantao = function(child){ for (var i in child){ child[i].editOpened(false); child[i].switchS(true); qiantao(child[i].children()); } } qiantao(menus[i].children()); menus[i].editOpened(false); menus[i].switchS(true); } }; //關閉當前彈出操做層 this.closeOpenedDiv = function(source){ source.editOpened(false); } }; var myMenuModel = new MenuModel(); ko.applyBindings(myMenuModel); var children = myMenuModel.menus(); for (var i in children){ if(children[i].children().length == 0 ){//存在子節 children[i].imageUrl("http://www.see-source.com/images/dhtmlgoodies_white.gif"); } } </script> <script type="text/javascript"> function getSelectedValues(){ //查看選中的值列表 var values = myMenuModel.selectedValues(); if(values.length != 0){ values = values.substring(1); } alert(values); } </script>以上代碼可直接粘貼運行。