Knockoutjs官网翻译系列(二) Observable 数组

      承接前文,前文书说道了KO框架中如何使用observable的视图模型属性来与UI元素进行绑定并自动进行双向更新的事儿。observable属性除了服务基础数据类型以外,还定义了专门为服务数组类型的observableArray。javascript

     若是你想要监测并响应一个object类型的变化,那么你使用observables。若是你想监测并响应一个集合的变化,就使用observableArray。不少场景下你都会用到它,好比你要在UI上展示或者编辑一个列表内容,期中你会控制他们的展示啊,隐藏啊,添加啊,删除之类的时候,使用它吧。看看下面的demo如何定义:html

 $(function () {
     var myObservableArray = ko.observableArray();    // 直接定义
     myObservableArray.push('Some value');

var myViewModel = {
names:ko.observableArray(); //定义在视图模型对象中
   } });

     注意: 一个observableArray只监测和跟踪集合中的对象,并不监测和跟踪集合中对象的属性,直观来说就是只关心内部元素的更新和删除以及排序等,并不关心对象属性是否发生变化。java

     简单的把一个对象放入observableArray中不会让该对象的属性也变成observable。固然若是你想的话你能够将这些对象的属性定义成observable的,这就是另外一回事儿了。 一个 observableArray 只是跟踪他们本身所包含的对象, 而且只会在对象增长或减小或排序的时候向监听器发送通知。数组

    observableArray的初始化浏览器

     若是你想让你的observableArray在一开始就有值,那么能够在构造函数中直接传入一个js数组,像下面这样:框架

 $(function () {
     var anotherObservableArray = ko.observableArray([
                { name: "Bungle", type: "Bear" },
                { name: "George", type: "Hippo" },
                { name: "Zippy", type: "Unknown" }
            ]);
     });

 

     读取observableArray信息函数

     其实在幕后一个observableArray实际上也是一个observable数据,只不过它的值是个数组(额外的,observableArray 添加了不少本身的特性)。因此你能够像方法同样调用它就能直接到里面的javascript数组,就像其余的observable的使用方式同样。而后就能够随意处理这个js数组了。举个例子:性能

$(function () {
    var anotherObservableArray = ko.observableArray([
        { name: "Bungle", type: "Bear" },
        { name: "George", type: "Hippo" },
        { name: "Zippy", type: "Unknown" }
    ]);

    alert('The length of the array is ' + myObservableArray().length);
    alert('The first element is ' + myObservableArray()[0]);
});

 

       从技术上来说你可使用任意的原生javascript数组中的方法来操做获取到的js数组,可是你也可使用KO框架中为observableArray提供的一些等效方法来直接操做而无需转换为js数组,有时候这更有效率 ,由于:spa

  1. 它们支持全部浏览器. (例如,原生的javascript数组中的indexOf方法不能在IE8或更早的浏览器版本中使用,可是KO中的indexOf就能完美支持。)
  2. 其中有一些能够修改数组内容的方法好比 pushsplice, 在KO中这些方法都自带自动触发和追踪机制,因此全部注册过的监听器一旦在数组内容发生变化的时候都能接收到通知,而且自动为你更新UI。
  3. 语法上也很是简单. 好比调用KO的push方法, 只须要这么写myObservableArray.push(...)。这样的话比先取出原生数组再调用原生数组的push方法要简单。(复杂的写法:myObservableArray().push(...)

      下面来看看它包含的一些常见方法:code

indexOf

indexOf 方法返回参数所表明的数据在数组中的索引下表,若是找到多个则只返回第一个的索引。例如:myObservableArray.indexOf('Blah') 返回数组中第一个内容为Blash的元素所表明的下表,下表从0开始。若是没有找到的话则返回-1。

 

 

slice

slice方法等效于原声javascript数组中的slice方法 (返回从你指定的起始下标位置到终止下标位置内的全部元素)。

pop, push, shift, unshift, reverse, sort, splice

这些方法都等效于原声javascirpt数组中的方法,可是他们都会向监听器发送通知,由于他们都会改变数组中的元素,包括增删排序。

  • push(value) — 添加一个新的元素到集合中。
  • pop() —删除数组中的最后一个元素并返回。
  • unshift( value ) — 在数组的开头插入一个新元素。
  • shift() — 删除数组的第一个元素并返回。
  • reverse() — 将数组中的全部元素顺序翻转并返回这个observableArray。
  • sort() — 排序数组并返回排序后的observableArray。
  • splice() — 从给定的起始索引位置删除指定数量的元素并返回这些删除的元素。示例:myObservableArray.splice(1, 3) 从位置1开始删除3个元素,而且将它们做为一个数组返回。

最后再说一下Sort:

默认的排序是按照字母进行排序的, 可是你能够传递一个函数来自定义排序规则。 你的函数须要提供两个参数,框架会将数组中的数据两两传递进去,若是你想让第一个元素排在前面,则返回一个负数,若是你想让第一个元素排在后面就返回一个正数,返回0的话相同的数据位置不变。举个例子, 经过last name排序一个 ‘person’ 集合 , 你能够这么写:myObservableArray.sort(function (left, right) { return left.lastName == right.lastName ? 0 : (left.lastName < right.lastName ? -1 : 1) })

remove 与removeAll

observableArray 添加了更多有用的方法 :

  • remove( someItem ) — 删除全部与someItem相同的值,并将它们做为数组返回。
  • remove( function (item) { return item.age < 18; } ) — 删除全部年龄小于18岁的元素,并将它们做为数组返回。
  • removeAll( ['Chad', 132, undefined] ) — 删除全部值为Chad、12三、undefined的元素并将它们做为数组返回。
  • removeAll() —删除全部元素一个不留。

延迟更新通知 

一般,一个observableArray内的元素发生改变时(增删排序)会当即向它的订阅者们发送通知。可是若是这个observableArray会屡次重复出现,或者更新会很耗时的时候你可能会但愿经过延迟通知的时间间隔来获取更好的性能体验,可使用rateLimitextender 来完成:

myViewModel.myObservableArray.extend({ rateLimit: 50 });

好啦,咱们下节见啦。

相关文章
相关标签/搜索