Knockout.Js案例二Working With Lists And Collections
案例一:Foreach绑定
通常,您要生成重复的UI元素,特别是当显示列表,用户可以添加和删除元素。KO.JS让你轻松,使用的数组和foreach绑定。
在接下来的几分钟,您将构建一个动态UI保留席位和吃饭——这可能是一个一步一个机票预订过程。在右下方的窗格中,您已经有了:
HTML:
<h2>Your seat reservations</h2>
<table>
<thead><tr>
<th>Passenger name</th><th>Meal</th><th>Surcharge</th><th></th>
</tr></thead>
<!-- Todo: Generate table body -->
<tbody data-bind="foreach: seats">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: meal().mealName"></td>
<td data-bind="text: meal().price"></td>
</tr>
</tbody>
</table>
JS:
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
}
SeatReservation,一个简单的JS的数,选择存储乘客名字和一顿饭
function ReservationsViewModel() {
var self = this;
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealName: "Standard (sandwich)", price: 0 },
{ mealName: "Premium (lobster)", price: 34.95 },
{ mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]);
}
ko.applyBindings(new ReservationsViewModel());
ReservationsViewModel:viewmodel类:
availableMeals: js对象提供餐数据,
seat:数组初始SeatReservation实例的集合。
请注意,这是一个observableArray——毫不奇怪,可见相当于一个常规数组中,这意味着它可以自动触发更新UI项添加或删除。
Notice that, because the meal property is an observable, it's important to invoke meal()as a function (to obtain its current value) before attempting to read sub-properties. In other words, write meal().price, not meal.price.
请注意,因为这顿饭属性是一个可观察到的,是很重要的()作为一个函数来调用餐(获得其当前值)之前sub-properties阅读。换句话说,写餐()。的价格,而不是meal.price。因为字段是可以观察到的,是很重要的,所以需要();
foreach is part of a family of control flow bindings that includes foreach, if, ifnot, and with. These make it possible to construct any kind of iterative, conditional, or nested UI based on your dynamic viewmodel.
foreach属于控制流绑定的一部分。这让我们构造任何类型的迭代,条件,或嵌套的基于动态viewmodel的UI
案例2:Add Item新增项
MVVM模式后使它非常简单的使用数组和层次等多变的对象图。你更新基础数据,UI自动更新同步。
实现增加座位预订:
添加一个按钮到视图,使用点击绑定关联与函数在你点击视图模型:
<button data-bind="click: addSeat">Reserve another seat</button>
然后实现addSeat函数,使其推动额外进入座位数组:
function ReservationsViewModel() {
var self = this;
// Non-editable catalog data - would come from the server
self.availableMeals = [
{ mealName: "Standard (sandwich)", price: 0 },
{ mealName: "Premium (lobster)", price: 34.95 },
{ mealName: "Ultimate (whole zebra)", price: 290 }
];
// Editable data
self.seats = ko.observableArray([
new SeatReservation("Steve", self.availableMeals[0]),
new SeatReservation("Bert", self.availableMeals[0])
]);
self.addSeat = function() {
self.seats.push(new SeatReservation("", self.availableMeals[0]));
}
}
试一试,现在当你点击“预订另一个座位”,UI更新以匹配。这是因为座位是可观察到的数组,所以添加或删除条目将自动触发更新UI。
注意,添加一行不涉及再生整个UI。为了提高效率,KO.JS跟踪改变在你的视图模型,并执行DOM更新以匹配的最小集合。这意味着您可以扩大规模非常大或复杂的ui,甚至它可以保持时髦和响应在低端移动设备.
案例三:使数据可以编辑
你可以使用绑定在foreach块和其他地方一样,所以很容易升级我们进入一个完整的数据编辑器。更新您需要的东西:
<tbody data-bind="foreach: seats">
<tr> <td><input data-bind="value: name" /></td> <td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td> <td data-bind="text: meal().price"></td> </tr> </tbody>
这段代码使用了两个新的绑定,选项和optionsText,一起控制两组可用的项目在一个下拉列表,和对象属性(在本例中,mealName)是用来表示屏幕上的每一项
现在试一试,你可以选择从可用的饭菜,和这样做会导致相应的行(只)刷新显示,饭菜的价格。
格式化Prices
我们有一个不错的面向对象的表示我们的数据,所以我们可以平凡地添加额外的属性和函数对象图的任何地方。让我们给SeatReservation类格式的能力自己的价格数据使用一些自定义的逻辑。
1function SeatReservation(name, initialMeal) {
2 var self = this;
3 self.name = name;
4 self.meal = ko.observable(initialMeal);
5
6 self.formattedPrice = ko.computed(function() {
7 var price = self.meal().price;
8 return price ? "$" + price.toFixed(2) : "None";
9 });
}
现在你可以更新视图使用了formattedPrice每个SeatReservation实例:
由于格式化的价格将计算基于所选餐,我们可以使用ko.computed代表(因此它将自动更新时餐选择更改):
function SeatReservation(name, initialMeal) {
var self = this;
self.name = name;
self.meal = ko.observable(initialMeal);
self.formattedPrice = ko.computed(function() {
var price = self.meal().price;
return price ? "$" + price.toFixed(2) : "None";
});
}
现在你可以更新视图使用了formattedPrice每个SeatReservation实例:
<tr>
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
<td data-bind="text: formattedPrice"></td>
5 </tr>
案例四:删除项目和总和
因为你可以添加条目,您应该能够删除它们,对吗?如您所料,这只是一个更新底层数据的问题。
更新你的视图,它显示每个条目旁边的“删除”链接
<tr>
<td><input data-bind="value: name" /></td>
<td><select data-bind="options: $root.availableMeals, value: meal, optionsText: 'mealName'"></select></td>
<td data-bind="text: formattedPrice"></td>
<td><a href="#" data-bind="click: $root.removeSeat">Remove</a></td>
</tr>
注意,$ root。前缀导致KO.JS寻找removeSeaf方法在你的顶层视图模型而不是SeatReservation实例绑定——这是一个更方便的地方把removeSeat这个例子。
因此,添加相应的removeSeat函数根viewmodel类,ReservationsViewModel:
1 function ReservationsViewModel() {
// ... leave the rest unchanged ...
// Operations
self.addSeat = function() { /* ... leave unchanged ... */ }
self.removeSeat = function(seat) { self.seats.remove(seat) }
}
现在,如果你运行应用程序时,您将能够删除物品以及添加它们。
显示一个总附加费:
最好是让客户知道他们要支付,对吗?毫不奇怪,我们可以定义为一个计算的属性,让框架照顾知道什么时候重新计算并刷新显示。
添加以下ko.computed ReservationsViewModel内:
self.totalSurcharge = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.seats().length; i++)
total += self.seats()[i].meal().price;
return total;
});
再次注意,因为座椅和饭都可见,我们调用函数来读他们的当前值(例如self.seats(). length)。
显示全部附加费通过添加以下< h3 >元素
<h3 data-bind="visible: totalSurcharge() > 0">
Total surcharge: $<span data-bind="text: totalSurcharge().toFixed(2)"></span>
</h3>
这段代码演示了两个点:
可见绑定使有形或无形的元素作为数据更改(在内部,它修改元素的CSS显示样式)。在本例中,我们选择只显示“总附加费”信息如果是大于零。
您可以使用任意JavaScript表达式内部声明式绑定。在这里,我们使用totalSurcharge()> 0和totalSurcharge().toFixed(2)。在内部,这实际上定义了一个属性来表示的输出,计算表达式。它只是一个非常轻量级的和方便的语法的选择。
现在,如果你运行代码,您将看到“总附加费”出现和消失,由于依赖跟踪,它知道什么时候重新计算自己的价值——你不需要任何代码在你的“增加”或“删除”功能,迫使依赖手动更新。
最后的细节:
随着MVVM模式,UI的一个面向对象的表示的数据和行为,你在一个好位置洒在额外的行为在一个非常自然和方便的方式。
例如,如果你要求显示的总数预留座位,您可以实现在一个地方,你不需要写任何额外代码以使座位数量更新当你添加或删除条目。只是更新< h2 >顶部的观点:
1 <h2>Your seat reservations (<span data-bind="text: seats().length"></span>)</h2>
同样,如果你要求限制数量的席位可以储备,说,可以使UI表示,通过使用使绑定:
按钮时座位限制成了残疾。你不必编写任何代码重新启用它,当用户删除一些席位(搞乱你的“删除”逻辑),因为表达式将自动重新评估相关数据变化时所击倒。
最后:如果你想学习的方法保存回服务器更新数据,看教程的加载和保存数据。
Knockout.Js案例二Working With Lists And Collections的更多相关文章
- Knockout.Js案例一Introduction
</strong></p> <p>Last name: <strong data-bind="text:lastName ">tod ...
- Knockout.Js案例三单页面应用程序
<ul data-bind="foreach: folders"> <li data-bind="text: $data">& ...
- 【Knockout.js 学习体验之旅】(2)花式捆绑
本文是[Knockout.js 学习体验之旅]系列文章的第2篇,所有demo均基于目前knockout.js的最新版本(3.4.0).小茄才识有限,文中若有不当之处,还望大家指出. 目录: [Knoc ...
- Knockout.js 组件
Knockout.js是一个基于MVVM模式的轻量级的前端框架,有多轻?根据官网上面显示的最新版本v3.4.0,仅22kb.能够友好地处理数据模型和界面DOM的绑定,最重要的是,它的绑定是双向的,也就 ...
- 通过Knockout.js + ASP.NET Web API构建一个简单的CRUD应用
REFERENCE FROM : http://www.cnblogs.com/artech/archive/2012/07/04/Knockout-web-api.html 较之面向最终消费者的网站 ...
- Knockout.js随手记(4)
动态绑定下拉列表 在<select> data-bind的options选项如果绑定到ko.observableArray(),就可以动态新增选项效果,也就是可以利用其完成常见的级联效果的 ...
- Knockout.Js官网学习(系列)
1.Knockout.Js官网学习(简介) 2.Knockout.Js官网学习(监控属性Observables) Knockout.Js官网学习(数组observable) 3.Knockout.Js ...
- 7.Knockout.Js(Mapping插件)
前言 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些属性是observable的,你可以使用KO绑定他们到你的UI元素上,当这些o ...
- MVC3.0+knockout.js+Ajax 实现简单的增删改查
MVC3.0+knockout.js+Ajax 实现简单的增删改查 自从到北京入职以来就再也没有接触MVC,很多都已经淡忘了,最近一直在看knockout.js 和webAPI,本来打算采用MVC+k ...
随机推荐
- ARPSpoofing教程(四) - 捕获并分析数据包
本程序的主要目标是展示如何解析所捕获的数据包的协议首部. 这个程序可以称为UDPdump,打印一些网络上传输的UDP数据的信息. 1: #include"pcap.h" 2: ty ...
- Linux运维工程师入门的10大实用工具
说到工具,在行外可以说是技能,在行内我们一般称为工具,就是运维必须要掌握的工具. 我就大概列出这几方面,这样入门就基本没问题了. 工具如下: 1.Linux系统基础 这个不用说了,是基础中的基础,连这 ...
- java编程思想-复用类总结
今天继续读<java 编程思想>,读到了复用类一章,看到总结写的很好,现贴上来,给大家分享. 继承和组合都能从现有类型生成新类型.组合一般是将现有类型作为新类型底层实现的一部分来加以复用, ...
- 深入剖析z-index属性
一.z-index七阶层叠顺序表 1.层叠顺序的大小比较: background/border < 负z-index < block块状水平盒子 < float浮动盒子 < i ...
- GridView数据格式化
一.动态生成列的格式化 此种GridView中的列是动态生成的,格式化可以通过RowDataBound事件进行.如下边代码,对第十列的值进行格式化. protected void gvUserList ...
- Curl http_code 状态码 意义及信息
shell命令:curl -I -m 10 -o /dev/null -s -w %{http_code} http://test.com curl_init — 初始化一个curl会话curl_co ...
- 当SVN服务器端IP地址发生变化时,客户端重新定位
第一种方法: 重新设置URL: 第二种方法: 找到客户端数据库文件 ,在隐藏的文件夹.svn中,找到文件夹中的文件 *.db文件 ,用SQLite打开,修改表Repository中的数据
- securecrt中文乱码
1.直接打开Linux的terminal中文字符显示正常,但是用securecrt登陆后中文显示不正常 解决方法:securecrt字符集设置不对 路径:Options -> Session O ...
- 固定IP 正常访问谷歌
如题 地址栏直接输入 http://173.194.1.150/ 正常使用 ~标记一下~
- Orchard源码分析(4.1):Orchard.Environment.CollectionOrderModule类
CollectionOrderModule类是一个Autofac模块(Module,将一系列组件和相关的功能包装在一起),而非Orchard模块.其作用是保证多个注册到容器的组件能按FIFO(Firs ...