magento2结算页面前端篇之knockoutjs中的observableArray

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

magento2结算页面前端篇之knockoutjs中的observableArray

如果你想检测并响应一个对象上的变化,你可以使用可观察的对象。如果您想检测和响应一系列对象的变化,请使用observableArray。这在许多场景中非常有用,在这些场景中,您正在显示或编辑多个值,并且需要在添加和删除项目时重复显示和消失UI的各个部分。
示例:

var myObservableArray = ko.observableArray();    // Initially an empty array
myObservableArray.push('Some value');            // Adds the value and notifies observers

关键点:ObservalArray跟踪数组中的对象,而不是这些对象的状态
简单地将一个对象放入observableArray并不能使该对象的所有属性本身都可见。当然,如果您愿意,您可以使这些属性可见,但这是一个独立的选择。observableArray只跟踪它持有的对象,并在添加或删除对象时通知侦听器。


预填充可观察的数组
如果希望可观察数组不以空开头,而是包含一些初始项,请将这些项作为数组传递给构造函数。例如:

// This observable array initially contains three objects
var anotherObservableArray = ko.observableArray([
    { name: "Bungle", type: "Bear" },
    { name: "George", type: "Hippo" },
    { name: "Zippy", type: "Unknown" }
]);

从## observableArray读取信息

在幕后,observableArray实际上是一个值为数组的可观察对象(另外,observableArray添加了一些下面描述的附加功能)。因此,您可以通过将ObservalArray作为一个无参数的函数调用来获取底层JavaScript数组,就像其他任何可观察对象一样。然后您可以从底层数组中读取信息。例如:

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

从技术上讲,您可以使用任何本机JavaScript数组函数来操作底层数组,但通常有更好的替代方法。KO的observableArray有自己的等效功能,它们更有用,因为:
它们适用于所有目标浏览器。(例如,本机JavaScript indexOf函数在ie8或更早版本上不起作用,但KO的indexOf可以在任何地方使用。)
对于修改数组内容的函数,如pushsplice,KO的方法会自动触发依赖项跟踪机制,以便将更改通知所有注册的侦听器,并且您的UI会自动更新,这意味着使用KO的方法(即ObservalArray.push)之间存在显著差异(…)和JavaScript本地数组方法(即observeArray().push(…),因为后者不会向数组的订阅者发送其内容已更改的任何通知。


indexOf
indexOf函数返回与参数相等的第一个数组项的索引。例如,myObservableArray.indexOf(‘Blah’)将返回第一个数组项的从零开始的索引,该索引等于Blah,如果找不到匹配值,则返回值-1。


slice
slice 函数是原生 JavaScript 切片函数的 observableArray 等价物(即,它返回从给定开始索引到给定结束索引的数组条目)。 调用 myObservableArray.slice(…) 相当于在底层数组上调用相同的方法(即 myObservableArray().slice(…))。


以下所有这些函数都相当于在底层数组上运行原生 JavaScript 数组函数,然后通知侦听器有关更改:
push( value ) — 在数组末尾添加一个新项目。
pop() — 从数组中删除最后一个值并返回它。
unshift( value ) — 在数组的开头插入一个新项目。
shift() — 从数组中删除第一个值并返回它。
reverse() — 反转数组的顺序并返回 observableArray(不是底层数组)。
sort() — 对数组内容进行排序并返回 observableArray。默认排序是按字母顺序排列的,但您可以选择传递一个函数来控制数组的排序方式。请参阅下面排序的示例。
splice() — 从给定索引开始移除并返回给定数量的元素。例如, myObservableArray.splice(1, 3) 从索引位置 1 开始删除三个元素(即第 2、第 3 和第 4 个元素)并将它们作为数组返回。


sorted和### reversed
sorted() — 返回数组的排序副本。 如果您想保留可观察数组的原始顺序但需要按特定顺序显示它,这比排序更可取。
默认排序是按字母顺序排列的,但您可以选择传递一个函数来控制数组的排序方式。 您的函数应该接受数组中的任意两个对象,如果第一个参数较小,则返回负值,正值表示第二个较小,或者为零以将它们视为相等。 例如,要按姓氏对“person”对象数组进行排序,您可以编写:

var mySortedArray = ko.pureComputed(function () {
    return myObservableArray.sorted(function (left, right) {
        return left.lastName === right.lastName ? 0
             : left.lastName < right.lastName ? -1
             : 1;
    });
});

reversed()— 返回数组的反转后的副本。


replace,remove和removeAll
observableArray 添加了一些默认在 JavaScript 数组中找不到的更有用的方法:
replace( oldItem, newItem ) — 用 newItem 替换与 oldItem 相等的第一个值。
remove( someItem ) — 删除所有等于 someItem 的值并将它们作为数组返回。
remove( function (item) { return item.age < 18; } ) — 删除所有年龄属性小于 18 的值,并将它们作为数组返回。
removeAll( [‘Chad’, 132, undefined] ) — 删除所有等于 ‘Chad’、123 或 undefined 的值,并将它们作为数组返回。
removeAll() — 删除所有值并将它们作为数组返回。


确定属性是否为 observableArray
在某些情况下,以编程方式确定您是否正在处理 observableArray 很有用。 Knockout 提供了一个实用函数 ko.isObservableArray 来帮助解决这种情况。


通常,一个 observableArray 会在它发生更改后立即通知其订阅者。 但是如果 observableArray 被重复更改或触发昂贵的更新,您可能会通过限制或延迟更改通知来获得更好的性能。 这是使用 rateLimit 扩展器完成的,如下所示:

// Ensure it notifies about changes no more than once per 50-millisecond period
myViewModel.myObservableArray.extend({ rateLimit: 50 });

跟踪数组更改
尽管您可以像任何其他 observable 一样订阅和访问 observableArray,但 Knockout 还提供了一种超快速方法来找出 observable 数组的变化情况(即,刚刚添加、删除或移动了哪些项目)。 您订阅数组更改如下:

obsArray.subscribe(fn, thisArg, "arrayChange");

订阅变更的主要优点:
在大多数情况下,性能是 O(1),即基本上没有性能影响,因为对于简单的操作,(推送、拼接等)Knockout 提供更改日志而不运行任何差异算法。 如果您在不使用典型的数组变异函数的情况下进行了任意更改,则 Knockout 仅依赖于算法。
更改日志只为您提供实际更改的项目。
以下是如何报告更改的示例:

var myArray = ko.observableArray(["Alpha", "Beta", "Gamma"]);
 
myArray.push("Delta");
// Changes: [{ index: 3, status: 'added', value: 'Delta' }]
// New value: ["Alpha", "Beta", "Gamma", "Delta"]
 
myArray.pop();
// Changes: [{ index: 3, status: 'deleted', value: 'Delta' }]
// New value: ["Alpha", "Beta", "Gamma"]
 
myArray.splice(1, 2, "Omega");
// Changes:
// [{ index: 1, status: 'deleted', value: 'Beta' },
//  { index: 1, status: 'added', value: 'Omega' },
//  { index: 2, status: 'deleted', value: 'Gamma' }]
// New value: ["Alpha", "Omega"]
 
myArray.reverse();
// Changes:
// [{ index: 0, moved: 1, status: 'deleted', value: 'Alpha' },
//  { index: 1, moved: 0, status: 'added', value: 'Alpha' }]
// New value: ["Omega", "Alpha"]

如上所示,更改报告为添加和删除值的列表。 删除项的索引引用原始数组,添加项的索引引用新数组。

当项目被重新排序时,如上面的最后一个例子所示,您还将获得移动的信息。 您可以选择忽略移动的信息,并将其解释为删除的原始 Alpha 和添加到数组末尾的不同 Alpha。 或者,您可以认识到移动的信息告诉您,您可以将添加和删除的值视为仅更改位置的同一项目(通过匹配索引)。

observableArray 在构造时启用了数组跟踪,但您可以扩展任何其他订阅(即 ko.observable 和 ko.computed),如下所示:

trackable = ko.observable().extend({trackArrayChanges: true});

magento2结算页面前端篇之knockoutjs中的observableArray

如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。