原文:Knockout应用开发指南 第八章:简单应用举例(2)

5   Control types

这个例子,对view model没有什么特殊的展示,只是展示如何绑定到各种元素上(例如,select, radio button等)。

代码: View

<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);


6   Templating

这个例子展示的render模板,以及在模板内部如何使用data binding属性的。

Template很容易嵌套,当任何依赖数据改变的时候,Knockout会自动重新render模板。参考演示(启用‘Show render times’),Knockout知道只需要重新render改变的那些数据所绑定的最近的模板。

代码: View

<div data-bind='template: "peopleTemplate"'>
</div>
<label>
<input type="checkbox" data-bind="checked: showRenderTimes"/>
Show render times</label>
<script type="text/html" id="peopleTemplate">
<h2>People</h2>
<ul>
{{each people}}
<li>
<div>
${ name } has <span data-bind="text: children().length">&nbsp;</span> children:
<a href="#" data-bind="click: addChild ">Add child</a>
<span class="renderTime" data-bind="visible: showRenderTimes">
(person rendered at <span data-bind="text: new Date().getSeconds()"></span>)
</span>
</div>
<div data-bind='template: { name: "childrenTemplate", data: children }'></div>
</li>
{{/each}}
</ul>
</script>
<script type="text/html" id="childrenTemplate">
<ul>
{{each $data}}
<li>
${ this }
<span class="renderTime" data-bind="visible: viewModel.showRenderTimes">
(child rendered at <span data-bind="text: new Date().getSeconds()"></span>)
</span>
</li>
{{/each}}
</ul>
</script>

代码: View model

// Define a "person" class that tracks its own name and children, and has a method to add a new child

var person = function (name, children) {
this.name = name;
this.children = ko.observableArray(children);

this.addChild = function () {
this.children.push("New child");
} .bind(this);
}

// The view model is an abstract description of the state of the UI, but without any knowledge of the UI technology (HTML)

var viewModel = {
people: [
new person("Annabelle", ["Arnie", "Anders", "Apple"]),
new person("Bertie", ["Boutros-Boutros", "Brianna", "Barbie", "Bee-bop"]),
new person("Charles", ["Cayenne", "Cleopatra"])
],
showRenderTimes: ko.observable(false)
};

ko.applyBindings(viewModel);


7   Paged grid

data-bind="..."绑定(像text, visible, 和click不是固定死的) - 你可以很容易自定义自己的绑定。如果你的自定义绑定仅仅是添加事件或者更新DOM元素的属性,那几行就可以实现。不过,你依然可以自定义可以重用的绑定(或插件),就行本例的simpleGrid绑定。

如果一个插件需要自己标准的view model(例如本例的ko.simpleGrid.viewModel ),它提供既提供了该如何配置插件实例(分页大小,列声明)工作,也提供了view model上的属性是否是observable 的(例如currentpage索引)。也可以扩展代码让这些属性很容易地改变,并且让UI自动更新。例如,“Jump to first page”按钮的工作原理。

查看HTML源代码可以看到非常容易使用这个simple grid插件。simpleGrid源码地址是:http://knockoutjs.com/examples/resources/knockout.simpleGrid.js

代码: View

<div data-bind="simpleGrid: gridViewModel"> </div>

<button data-bind='click: function() { items.push({ name: "New item", sales: 0, price: 100 }) }'>
Add item
</button>

<button data-bind="click: sortByName">
Sort by name
</button>

<button data-bind="click: function() { gridViewModel.currentPageIndex(0) }">
Jump to first page
</button>

代码: View model

var myModel = {
items: ko.observableArray([
{ name: "Well-Travelled Kitten", sales: 352, price: 75.95 },
{ name: "Speedy Coyote", sales: 89, price: 190.00 },
{ name: "Furious Lizard", sales: 152, price: 25.00 },
{ name: "Indifferent Monkey", sales: 1, price: 99.95 },
{ name: "Brooding Dragon", sales: 0, price: 6350 },
{ name: "Ingenious Tadpole", sales: 39450, price: 0.35 },
{ name: "Optimistic Snail", sales: 420, price: 1.50 }
]),

sortByName: function () {
this.items.sort(function (a, b) {
return a.name < b.name ? -1 : 1;
});
}
};

myModel.gridViewModel = new ko.simpleGrid.viewModel({
data: myModel.items,
columns: [
{ headerText: "Item Name", rowText: "name" },
{ headerText: "Sales Count", rowText: "sales" },
{ headerText: "Price", rowText: function (item) { return "$" + item.price.toFixed(2) } }
],
pageSize: 4
});

ko.applyBindings(myModel);


8   Animated transitions

该例子展示了2种方式实现动画过渡效果:

当使用template/foreach绑定的时候,你可以使用afterAdd和beforeRemove回调函数,他们可以让你写代码真实操作添加和删除元素,这样你就可以使用像jQuery的 slideUp/slideDown()这样的动画效果。在planet types之间切换或添加新的planet可以看到效果。

通过observable 类型的值,我们不难定义自己的Knockout绑定,查看HTML源代码可以看到一个自定义绑定fadeVisible,不管什么时候它改变了, jQuery就会在相关的元素上执行fadeIn/fadeOut动画效果。点击“advanced options” checkbox 可以看到效果。

代码: View

<h2>Planets</h2>
<p>
<label>
<input type="checkbox" data-bind="checked: displayAdvancedOptions"/>
Display advanced options
</label>
</p>
<p data-bind="fadeVisible: displayAdvancedOptions">
Show:
<label><input type="radio" value="all" data-bind="checked: typeToShow"/>All</label>
<label><input type="radio" value="rock" data-bind="checked: typeToShow"/>Rocky planets</label>
<label><input type="radio" value="gasgiant" data-bind="checked: typeToShow"/>Gas giants</label>
</p>
<div data-bind='template: { name: "planetsTemplate",
foreach: planetsToShow,
beforeRemove: function(elem) { $(elem).slideUp(function() { $(elem).remove(); }) },
afterAdd: function(elem) { $(elem).hide().slideDown() } }'>
</div>
<script type="text/html" id="planetsTemplate">
<div class="planet ${ type }">${ name }</div>
</script>
<p data-bind="fadeVisible: displayAdvancedOptions">
<button data-bind='click: function() { addPlanet("rock") }'>
Add rocky planet</button>
<button data-bind='click: function() { addPlanet("gasgiant") }'>
Add gas giant</button>
</p>

代码: View model

var viewModel = {
planets: ko.observableArray([
{ name: "Mercury", type: "rock" },
{ name: "Venus", type: "rock" },
{ name: "Earth", type: "rock" },
{ name: "Mars", type: "rock" },
{ name: "Jupiter", type: "gasgiant" },
{ name: "Saturn", type: "gasgiant" },
{ name: "Uranus", type: "gasgiant" },
{ name: "Neptune", type: "gasgiant" },
{ name: "Pluto", type: "rock" }
]),

typeToShow: ko.observable("all"),
displayAdvancedOptions: ko.observable(false),

addPlanet: function (type) { this.planets.push({ name: "New planet", type: type }); }
};

viewModel.planetsToShow = ko.dependentObservable(function () {
// Represents a filtered list of planets
// i.e., only those matching the "typeToShow" condition

var desiredType = this.typeToShow();

if (desiredType == "all")
return this.planets();

return ko.utils.arrayFilter(this.planets(), function (planet) {
return planet.type == desiredType;
});
} .bind(viewModel));

// Here's a custom Knockout binding that makes elements shown/hidden via jQuery's fadeIn()/fadeOut() methods
// Could be stored in a separate utility library

ko.bindingHandlers.fadeVisible = {
init: function (element, valueAccessor) {
// Initially set the element to be instantly visible/hidden depending on the value
var value = valueAccessor();

$(element).toggle(ko.utils.unwrapObservable(value));
// Use "unwrapObservable" so we can handle values that may or may not be observable
},

update: function (element, valueAccessor) {
// Whenever the value subsequently changes, slowly fade the element in or out
var value = valueAccessor();
ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut();
}
};

ko.applyBindings(viewModel);



Knockout应用开发指南 第八章:简单应用举例(2)的更多相关文章

  1. Knockout应用开发指南 第八章:简单应用举例(1)

    原文:Knockout应用开发指南 第八章:简单应用举例(1) 本章展示的4个例子主要是利用了Knockout的基本语法特性,让大家感受到使用Kncokout的快感. 1   Hello world ...

  2. Knockout应用开发指南 应用举例(简单、高级)

    Knockout应用开发指南 第八章:简单应用举例(1)http://www.cnblogs.com/TomXu/archive/2011/11/30/2257067.htmlKnockout应用开发 ...

  3. Knockout应用开发指南(完整版) 目录索引

    http://learn.knockoutjs.com/  所有示例和代码都在在上面直接运行预览 注意:因为它用了google的cdn加速,所要要用代_理+_翻_墙才能正常加载 使用Knockout有 ...

  4. Knockout应用开发指南

    Knockout应用开发指南 第一章:入门 2011-11-21 14:20 by 汤姆大叔, 20799 阅读, 17 评论, 收藏, 编辑 1    Knockout简介 (Introductio ...

  5. Knockout应用开发指南(完整版) 目录索引(转)

    使用Knockout有一段时间了(确切的说从MIX11大会宣传该JavaScript类库以来,我们就在使用,目前已经在正式的asp.net MVC项目中使用),Knockout使用js代码达到双向绑定 ...

  6. Knockout应用开发指南 第七章:Mapping插件

    原文:Knockout应用开发指南 第七章:Mapping插件 Mapping插件 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些 ...

  7. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  8. Knockout应用开发指南 第四章:模板绑定

    原文:Knockout应用开发指南 第四章:模板绑定 模板绑定The template binding 目的 template绑定通过模板将数据render到页面.模板绑定对于构建嵌套结构的页面非常方 ...

  9. Knockout应用开发指南 第三章:绑定语法(2)

    原文:Knockout应用开发指南 第三章:绑定语法(2) 7   click 绑定 目的 click绑定在DOM元素上添加事件句柄以便元素被点击的时候执行定义的JavaScript 函数.大部分是用 ...

随机推荐

  1. .net程序员面试不完全指南

    程序员找工作难,想要被成功聘用更难.最常见的办法是经历一次又一次的面试失败后自己琢磨出面试技巧,当然也可以花钱到一些培训机构去接受专业的书面简历和模拟面试的指导.这些方法可能都会奏效,但是却并不是时间 ...

  2. WordPress数据备份

    服务器钱用光了要关了或者是服务器想要搬家,需要备份各种数据. 今天简单的备份了一下在服务器上面wordpress各种文件和资源. wordpress的数据主要分两个部分,一个是文字部分的:一个是附件部 ...

  3. hdu 1387 Team Queue (链表)

    题目大意: 不同的人在不同的队伍里,插入链表的时候假设这个链表里有他的队友,就把它放到最后一个队友的最后.假设没有队友,就把它放到整个链表的最后面. 出链表的时候把第一个人拿出来. 思路分析: 要模拟 ...

  4. Firemonkey 自定义Button的Style

    这篇文章模仿HTML中基于CSS的Button,通过Style实现自定义样式的Button. 前言 主要模仿的CSS代码如下: CSS Code 123456789101112131415161718 ...

  5. Linux下同时运行不同版本的qt程序

    因项目需要,可能有不同版本的qt程序要运行到同一台机器上,本次实验是qt4.8.5和qt5.3.1开发的程序同时运行在同一台机器上,此机器可以不按照qt的任何版本,当然,两个版本开发的qt与机器的位数 ...

  6. 默认情况下,不使用of子句表示在select所有的数据表中加锁(转)

    Select …forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不 ...

  7. linux exec和文件描述符妙用技巧(转)

    最近在看<精通unix shell脚本编程>时,看到exec<$1 exec 1>$OUTFILE,一下看的我就蒙了.网上看了大半天,终于搞定,记录如下.对于 Linux 而言 ...

  8. 使MYSQL能被外部访问_xeyuu_新浪博客

    使MYSQL能被外部访问_xeyuu_新浪博客 使MYSQL能被外部访问 (

  9. Swift - 页控件(UIPageControl)的用法

    使用页控件可以用来展示多个桌面.比如很多应用第一次登陆时,会在开始页面使用页控件来介绍功能,通过左右滑动来切换页. 通常我们使用UIPageControl和UIScrollView相互结合来实现多页切 ...

  10. innerHTML与appendChild(newnodeText)的区别

    innerHTML和createTextNode都可以把一段内容添加到一个节点中,区别是如果这段内容中有html标签时表现就不同了,在createTextNode中会当作文本处理,不会被浏览器解析,但 ...