参考:
http://www.cnblogs.com/TomXu/archive/2011/11/21/2257154.html
http://knockoutjs.com/documentation/introduction.html
<p>{{greeting}}</p> <!-- 或者 --> <p ng-bind=”greeting”></p>
<form ng-controller=”SomeController”> <input type=”checkbox” ng-model=”youCheckedIt”> </form>
<ul ng-controller=’StudentController’> <li ng-repeat=’student in students’> <a href=’/student/view/{{student.id}}’>{{student.name}}</a> </li> </ul>
<table ng-controller=’AlbumController’> <tr ng-repeat=’track in album’> <td>{{$index+1}}</td> <td>{{track.name}}</td> <td>{{track.duration}}</td> </tr> </table>
使用$watch监控数据模型的变化
示例代码出现错误,显示jquery-tmpl版本太久,参考解决办法。jquery.tmpl.js的下载地址:
https://raw.githubusercontent.com/BorisMoore/jquery-tmpl/master/jquery.tmpl.js
https://github.com/BorisMoore/jquery-tmpl
库的在线引用地址:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <script type="text/javascript" src="./jquery.tmpl.js"></script> <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-latest.js"></script>
重要概念:
启用绑定
ko.applyBindings(viewModel)
数据模型
var viewModel = { chosenMeal: ko.observable(availableMeals[0]) }
数据
var availableMeals = [ { mealName: 'Standard', description: 'Dry crusts of bread', extraCost: 0 }, { mealName: 'Premium', description: 'Fresh bread with cheese', extraCost: 9.95 }, { mealName: 'Deluxe', description: 'Caviar and vintage Dr Pepper', extraCost: 18.50 } ];
使用绑定,写变量
Chosen meal: <select data-bind="options: availableMeals, optionsText: 'mealName', value: chosenMeal"></select>
使用绑定,读变量,并作为参数提供给函数
<p> You've chosen: <b data-bind="text: chosenMeal().description"></b> (price: <span data-bind='text: formatPrice(chosenMeal().extraCost)'></span>) </p> <script> function formatPrice(price) { return price == 0 ? "Free" : "$" + price.toFixed(2); } </script>
概念
observables, Dependent Observables, Observable Array
核心功能
observables 可观察变量 Dependency tracking 依赖跟踪
declarative bindings 显式绑定
templating 模板
View-Model 视图模型
激活Knockout
ko.applyBindings(myViewModel, document.getElementById('someElementId'))
可观察变量,声明
var myViewModel = { personName: ko.observable('Bob'), personAge: ko.observable(123) };
可观察变量,读写
读:myViewModel.personAge()
写:myViewModel.personName('Mary'),支持链式语法
绑定,data-bind,注册到可观察变量
可观察变量,显示订阅
var subscription = myViewModel.personName.subscribe(function (newValue) { /* do stuff */ }); // ...then later... subscription.dispose(); // I no longer want notifications
依赖可观察变量
var viewModel = { firstName: ko.observable('Bob'), lastName: ko.observable('Smith') }; viewModel.fullName = ko.dependentObservable(function () { return this.firstName() + " " + this.lastName(); }, viewModel);
从依赖变量写入可观察变量
viewModel.fullName = ko.dependentObservable({ read: function () { return this.firstName() + " " + this.lastName(); }, write: function (value) { var lastSpacePos = value.lastIndexOf(" "); if (lastSpacePos > 0) { // Ignore values with no space character this.firstName(value.substring(0, lastSpacePos)); // Update "firstName" this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName" } }, owner: viewModel });
使用依赖变量数组observable array
var myObservableArray = ko.observableArray(); // Initially an empty array myObservableArray.push('Some value'); // Adds the value and notifies observers // This observable array initially contains three objects var anotherObservableArray = ko.observableArray([ { name: "Bungle", type: "Bear" }, { name: "George", type: "Hippo" }, { name: "Zippy", type: "Unknown" } ]);
js等价读取信息:length, indexOf, slice
js数组等价操作:pop, push, shift, unshift, reverse, sort, splice
特殊操作:remove, removeAll
visible: 绑定到DOM元素,控制元素是否显示
text: 控制元素的文本值
html: 控制元素显示的HTML值
css: 添加或删除一个或多个CSS class到DOM元素上
style: 添加或删除一个或多个DOM元素上的style值
attr: 提供了一种方式可以设置DOM元素的任何属性值
click
event, 例如keypress, mouseover, mouseout
submit
enable
disable
value, <input>, <select>, <textarea>
checked, <input type=’checkbox’>, <input type=’radio’>
options, <select>, <select size=’6’>
selectedOptions, multi-select
uniqueName
使用jquery.tmpl,你可以使用任何你模板引擎支持的语法。jquery.tmpl执行如下语法:
${ someValue } — 参考文档
{{html someValue}} — 参考文档
{{if someCondition}} — 参考文档
{{else someCondition}} — 参考文档
{{each someArray}} — 参考文档
创建自定义绑定要在ko.bingdinghandlers中注册你的绑定名称,完成初始动作和更新动作
ko.bindingHandlers.yourBindingName = { init: function(element, valueAccessor, allBindingsAccessor, viewModel) { // This will be called when the binding is first applied to an element // Set up any initial state, event handlers, etc. here }, 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. } };
例如,我一般通过visible绑定控制一个元素的可见性,但是你希望更进一步能够动画显示这种转换。你希望元素根据一个绑定值slide in和slide out,你可以自定义一个绑定,在其中使用jQuery的 slideUp/slideDown功能。
ko.bindingHandlers.slideVisible = { update: function(element, valueAccessor, allBindings) { // First get the latest data that we're bound to var value = valueAccessor(); // Next, whether or not the supplied model property is observable, get its current value var valueUnwrapped = ko.unwrap(value); // Grab some more data from another binding property var duration = allBindings.get('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>
加载或保存数据:例如使用jQuery的$.getJSON, $.post, $.ajax
转化ViewModel数据到JSON格式,有时需要json2.js类库
ko.toJS 转化为JS对象
ko.toJSON 转化为JSON字符串
使用JSON更新ViewModel数据
手动方式
// 载入冰解析JSON var someJSON = /* 使用你期望的任何方法获取JSON */ var parsed = JSON.parse(someJSON); // 更新view model属性 viewModel.firstName(parsed.firstName); viewModel.pets(parsed.pets);
或者使用 knockout.mapping
var viewModel = ko.mapping.fromJS(data); //创建ViewModel ko.mapping.fromJS(data, viewModel); //更新ViewModel
用法:
key, create, update, ignore, include, copy
var viewModel = { firstName: ko.observable("Planet"), lastName: ko.observable("Earth") }; viewModel.fullName = ko.dependentObservable({ read: function() { return this.firstName() + " " + this.lastName(); }, write: function(value) { var lastSpacePos = value.lastIndexOf(" "); if (lastSpacePos > 0) { // Ignore values with no space character this.firstName(value.substring(0, lastSpacePos)); // Update "firstName" this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName" } }, owner: viewModel });
var clickCounterViewModel = function() { this.numberOfClicks = ko.observable(0); this.registerClick = function() { this.numberOfClicks(this.numberOfClicks() + 1); } this.hasClickedTooManyTimes = ko.dependentObservable(function() { return this.numberOfClicks() >= 3; }, this); }; ko.applyBindings(new clickCounterViewModel());
常用的控件
源代码:视图
<div class="readout"> <h3>What's in the model?</h3> <table> <tr> <td class="label">Text value:</td> <td data-bind="text: stringValue"></td> </tr> <tr> <td class="label">Password:</td> <td data-bind="text: passwordValue"></td> </tr> <tr> <td class="label">Bool value:</td> <td data-bind='text: booleanValue() ? "True" : "False"'></td> </tr> <tr> <td class="label">Selected option:</td> <td data-bind="text: selectedOptionValue"></td> </tr> <tr> <td class="label">Multi-selected options:</td> <td data-bind="text: multipleSelectedOptionValues"></td> </tr> <tr> <td class="label">Radio button selection:</td> <td data-bind="text: radioSelectedOptionValue"></td> </tr> </table> </div> <h3>HTML controls</h3> <table> <tr> <td class="label">Text value (updates on change):</td> <td><input data-bind="value: stringValue" /></td> </tr> <tr> <td class="label">Text value (updates on keystroke):</td> <td><input data-bind='value: stringValue, valueUpdate: "afterkeydown"' /></td> </tr> <tr> <td class="label">Text value (multi-line):</td> <td><textarea data-bind="value: stringValue"> </textarea></td> </tr> <tr> <td class="label">Password:</td> <td><input type="password" data-bind="value: passwordValue" /></td> </tr> <tr> <td class="label">Checkbox:</td> <td><input type="checkbox" data-bind="checked: booleanValue" /></td> </tr> <tr> <td class="label">Drop-down list:</td> <td><select data-bind="options: optionValues, value: selectedOptionValue"></select></td> </tr> <tr> <td class="label">Multi-select drop-down list:</td> <td><select multiple="multiple" data-bind="options: optionValues, selectedOptions: multipleSelectedOptionValues"></select></td> </tr> <tr> <td class="label">Radio buttons:</td> <td> <label><input type="radio" value="Alpha" data-bind="checked: radioSelectedOptionValue" />Alpha</label> <label><input type="radio" value="Beta" data-bind="checked: radioSelectedOptionValue" />Beta</label> <label><input type="radio" value="Gamma" data-bind="checked: radioSelectedOptionValue" />Gamma</label> </td> </tr> </table>
源代码:View Model
var viewModel = { stringValue : ko.observable("Hello"), passwordValue : ko.observable("mypass"), booleanValue : ko.observable(true), optionValues : ["Alpha", "Beta", "Gamma"], selectedOptionValue : ko.observable("Gamma"), multipleSelectedOptionValues : ko.observable(["Alpha"]), radioSelectedOptionValue : ko.observable("Beta") }; ko.applyBindings(viewModel);