Knockout学习笔记(二)

这篇文章主要用于记录学习Working with observable arrays的测试和体会。

Observable主要用于单一个体的修改订阅,当我们在处理一堆个体时,当UI需要重复显示一些样式相同的元素时,这些数据的绑定就需要依靠observable arrays。

特别需要注意的一点是,observable arrays关注的是数组中元素整体的变化(包括增加元素,删减元素,元素顺序的改变等等),而不是元素个体的变化(元素内部某些部分的改变)。

我们可以在js文件中创建一个observable array并初始化其中的一些元素:

1 var myObservableArray = ko.observableArray([
2   { firstName: "Kazusa", lastName: "Touma" },
3   { firstName: "Chiaki", lastName: "Izumi" },
4   { firstName: "Yuki", lastName: "Nagato" }
5 ]);

按照文档的原话:an observableArray is actually an observable whose value is an array。也就是说一个observableArray实际上就是一个observable,只不过这个observable的值是一个数组,而不是一个字符串或是数字等其他类型。在上一篇文章中,我们也可以观察到,在调用或者是修改observable的值得时候,我们要把它当做一个函数来使用,即在identifier之后要增加一个括号,这一法则也适用于observableArray(毕竟它本质上就是一个observable,事实上我在想为什么knockout不直接把observableArray的构造函数整合到observable之中去,可能是考虑到所有的方法不一样吧,也可能是为了在概念上更为清晰一些)。为了获取和修改observableArray的值或是其中的元素,我们创建了几个p元素用于显示:

1 <p>The length of observableArray is: <span id="lengthOfArray"></span></p>
2 <p>The second element of observableArray is: <span id="secondElement"></span></p>
3 <p>The changed element: <span id="changedElement"></span></p>

而在js文件中,我们做了以下操作:

1 $("#lengthOfArray").text(myObservableArray().length);
2 $("#secondElement").text(myObservableArray()[1].firstName);
3 myObservableArray()[2].lastName = "Charlie";
4 $("#changedElement").text(myObservableArray()[2].lastName);

最后页面显示如下:

一般说来,我们能够使用类似javascript中的最基本的数组操作方法来对observableArray进行操作,但是KO的observableArray拥有更为强大的特性,归纳为以下三点:

  1. 它们能够在所有浏览器上使用(例如javascript的indexof方法不能再IE8以前的浏览器上使用,而KO的indexof方法则可以使用)。
  2. 对于修改数组内容的方法,比如push或是splice,KO的方法会自动触发依赖跟踪机制并使得所有的订阅者和UI进行自动的改变。
  3. KO的方法在调用起来更为简洁,比如push方法只需要写成myObservableArray.push(...)而不是原先的myObservableArray().push(...)。

对于第三条我是存在一些疑问的:哪些方法可以省略括号,哪些方法不能省略括号呢?(至少length就不能,大概是因为length算作属性而不算方法的原因?)目前基本猜测是方法可以省略括号,而属性或元素不行。

之后的文档主要介绍的是读写数组信息所能用到的一些函数。为了能够更为直观地展现我的observableArray数组,我对js文件做了以下修改:

1 var i, length;
2 for (i = 0, length = myObservableArray().length; i < length; i++) {
3   $("<p></p>").appendTo($("p:last"));
4   $("p:last").text("First Name: " + myObservableArray()[i].firstName + "; Last Name: " + myObservableArray()[i].lastName);
5 }

Indexof方法可以返回数组中等于你所提供的参数的第一个元素的索引值,如果数组中不存在满足条件的元素,则返回-1,相应的js部分如下:

1 $("#indexOfChiaki").text(myObservableArray.indexOf("Chiaki"));
2 $("#indexOfCharlie").text(myObservableArray.indexOf("Charlie"));

相应的html部分如下:

1 <p>The index of Chiaki is: <span id="indexOfChiaki"></span></p>
2 <p>The index of Charlie is: <span id="indexOfCharlie"></span></p>

效果如下:

Slice方法用于返回数组中指定范围的元素值(如果省略第二个参数,则默认从第一个参数的位置到数组结尾),相应的js部分如下:

1 $("#testForSlice").text(myObservableArray.slice(2, 5));

相应的html部分如下:

1 <p>Test for slice function: <span id="testForSlice"></span></p>

效果如下:

假定我们的observableArray的元素就以上图为初始状态,接下来对pop、push、shift等方法进行测试。每个方法的效果图都在左边附加了原先的数组样式。

push用于在数组末尾添加指定的元素,相应的js部分如下:

1 myObservableArray.push("Charlie");

效果如下:

pop方法用于删除并返回数组的最后一个元素,相应的js部分如下:

1 var test = myObservableArray.pop();
2 alert(test);

效果如下:

unshift方法用于在数组首部添加一个指定的元素,相应的js部分如下:

1 myObservableArray.unshift("Charlie");

效果如下:

shift方法用于删除并返回数组开头的元素,相应的js部分如下:

1 var test = myObservableArray.shift();
2 alert(test);

效果如下:

reverse方法用于倒置数组的顺序,相应的js部分如下:

1 myObservableArray.reverse();

效果如下:

sort方法用于对数组进行排序,默认的排序规则是按照字母的顺序排序,相应的js部分如下:

1 myObservableArray.sort();

效果如下:

另外,sort方法也可以自定义排序的方式,比如自定义一个按字母倒序排列的方法:

1 myObservableArray.sort(function(left, right) {
2   return left === right ? 0 : (left < right ? 1 : -1);
3 });

效果如下:

关于sort自定义的排序方法,我是有一点疑问的,提供给function的两个参数left和right是怎样实现排序的?比较后所需要返回的正负数值又是如何应用到排序中去的?也许这些可以从knockout的源代码中找到答案,可留作以后研究。

splice方法删除并返回数组中从指定位置开始的指定数量的元素,它的第一个参数是指定的index的值,第二个参数则是需要删除的元素个数,相应的js部分如下:

1 var test = myObservableArray.splice(1, 3);
2 alert(test);

效果如下:

对于更为详尽的array方面可以使用的方法,MDN上有详尽的文档。

以下的方法都是javascript的默认方法中所没有的KO的新方法。

为了能够测试remove等方法的效果,我将数组元素变成如下形式:

remove方法可以删除等于指定值的元素并将它们以数组的方式返回,相应的js部分如下:

1 var test = myObservableArray.remove("Chiaki");
2 alert(test);

效果如下:

也可以在remove中自定义删除的条件,相应的js部分如下:

1 var test = myObservableArray.remove(function(item) {
2   return item.length <= 5;
3 });
4 alert(test);

效果如下:

removeAll方法用于删除等于指定数组中某一元素的元素并将其以数组的方式返回,相应的js部分如下:

1 var test = myObservableArray.removeAll(["Chiaki", "Kazusa", "Charlie"]);
2 alert(test);

效果如下:

如果在removeAll方法中不添加参数,则将会删除整个数组并返回,这里不再演示。

由于destroy和destroyAll方法主要是与Ruby和Rails开发相关,可以留作以后研究。

同样的,observableArray也可以调用extend方法中的rateLimit属性来指定延时,留作之后激活bindings时再测试。

Knockout学习笔记(二),布布扣,bubuko.com

时间: 2024-10-01 08:20:36

Knockout学习笔记(二)的相关文章

Knockout学习笔记(四)

由于Writable computed observables和How dependency tracking works的要求相对较高,我先跳过这两篇,学习Pure computed observables. Pure computed observables相对于一般的computed observables,在性能和存储上有优势,这是因为pure computed observables在不存在订阅者的时候是不会保持订阅关系的.这也使得pure computed observables有如

.Knockout学习笔记(五)

作为一名初学者来说,一篇篇的按顺序看官网上的文档的确是一件很痛苦的事情,毕竟它的排列也并非是由浅及深的排列,其中的顺序也颇耐人寻味,于是这篇文章我又跳过了Reference部分,进而进入到具体的bindings环节,首先接触到的是Controlling text and appearance. Visible binding会依据绑定的数据来决定相应的DOM元素是否隐藏. 我们首先在js文件部分定义一个view model,这里我创建的是一个object而不是一个构造函数,个人分析认为,obje

Caliburn.Micro学习笔记(二)----Actions

Caliburn.Micro学习笔记(二)----Actions 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions,看一下Caliburn.Micro给我们提供了多强大的支持 我们还是从做例子开始 demo的源码下载在文章的最后 例子1.无参数方法调用 点击button把textBox输入的文本弹出来 如果textbox里没有文本button不可点,看一下效果图 看一下前台代码 <Stac

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

JavaScript--基于对象的脚本语言学习笔记(二)

第二部分:DOM编程 1.文档象模型(DOM)提供了访问结构化文档的一种方式,很多语言自己的DOM解析器. DOM解析器就是完成结构化文档和DOM树之间的转换关系. DOM解析器解析结构化文档:将磁盘上的结构化文档转换成内存中的DOM树 从DOM树输出结构化文档:将内存中的DOM树转换成磁盘上的结构化文档 2.DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML属性,该属性代表该元素的"内容",即返回的某个元素的开始标签.结束标签之间的字符串内容(不包含其它

马哥学习笔记二十四——分布式复制快设备drbd

DRBD: 主从 primary: 可执行读.写操作 secondary: 文件系统不能挂载 DRBD: dual primay, 双主(基于集群文件系统的高可用集群) 磁盘调度器:合并读请求,合并写请求: Procotol:drbd数据同步协议 A: Async, 异步  数据发送到本机tcp/ip协议栈 B:semi sync, 半同步  数据发送到对方tcp/ip协议 C:sync, 同步  数据到达对方存储设备 DRBD Source: DRBD资源 资源名称:可以是除了空白字符外的任意

【Unity 3D】学习笔记二十八:unity工具类

unity为开发者提供了很多方便开发的工具,他们都是由系统封装的一些功能和方法.比如说:实现时间的time类,获取随机数的Random.Range( )方法等等. 时间类 time类,主要用来获取当前的系统时间. using UnityEngine; using System.Collections; public class Script_04_13 : MonoBehaviour { void OnGUI() { GUILayout.Label("当前游戏时间:" + Time.t

Spring Batch学习笔记二

此系列博客皆为学习Spring Batch时的一些笔记: Spring Batch的架构 一个Batch Job是指一系列有序的Step的集合,它们作为预定义流程的一部分而被执行: Step代表一个自定义的工作单元,它是Job的主要构件块:每一个Step由三部分组成:ItemReader.ItemProcessor.ItemWriter:这三个部分将执行在每一条被处理的记录上,ItemReader读取每一条记录,然后传递给ItemProcessor处理,最后交给ItemWriter做持久化:It