Knockout JS - 在没有 ko.mapping 的情况下观察数组的任何属性中的突变

Posted

技术标签:

【中文标题】Knockout JS - 在没有 ko.mapping 的情况下观察数组的任何属性中的突变【英文标题】:Knockout JS - observing a mutation in any property of an array without ko.mapping 【发布时间】:2018-09-23 23:02:15 【问题描述】:

在我的应用程序中,我必须只显示一个长列表中评分最高的前 5 项。我已经实现了如下:

长列表是一个数组,我用 ko.mapping 将它变成了一个可观察数组,其中所有元素都作为可观察对象,前 5 项是一个依赖于长列表的计算数组。每当长列表中的任何内容发生更改时,计算数组都会使用长列表并获取前 5 项。

我的问题是带有 ko.mapping 的长数组占用了 60MB 内存,而没有 ko.mapping 它只需要 4MB。有没有办法在不 ko.mapping 长数组的情况下达到这个效果?

这是一个fiddle,我在其中使用更小更简单的长数组重新创建了场景,但这只是为了让您理解我在说什么。

这是一个长数组,在演示中我将其设置为 12 个元素:

 this.longArray = ko.mapping.fromJS([
    name:"Annabelle",
    name:"Vertie",
    name:"Charles",
    name:"John",
    name:"AB",
    name:"AC",
    name:"AD",
    name:"AE",
    name:"AF",
    name:"AG",
    name:"AH",
    name:"AJ"
]);

这是计算出来的数组(只显示前 5 个):

this.sortedTopItems = ko.computed(function() 
    return self.longArray().sort(function(a, b)  
        if(a.name() < b.name()) return -1;
            if(a.name() > b.name()) return 1;
            return 0;
    ).slice(0, 5);
, this);

更改一键模拟长数组变化,重置键将数组重置为初始状态。

【问题讨论】:

【参考方案1】:

当然可以,但最简单的方法是在淘汰赛之前过滤数据。如果您只关心前 5 个。假设您的一长串项目称为data。请注意,我现在无法对此进行测试,但它应该会给您一个好主意。

const sortedTopItems = ko.observableArray([]);

// Call with new data
const update = (data) => 
    data.sort((a,b) => a.name - b.name);
    sortedTopItems(data.slice(0, 5));

这可以处理无法观察到的简单数据的情况。如果您希望实际数据项(行)是可观察的,那么我会执行以下操作:

const length = 5;

// Create an empty array and initialize as the observable
const startData = new Array(length).map(a => ());
const sortedTopItems = ko.observableArray(startData);

// Call with new data
const update = (data) => 
    data.sort((a,b) => a.name - b.name);

    for(let i = 0; i < length; i++) 
        const item = sortedTopItems()[i];
        ko.mapping.fromJS(data[i], item); // Updates the viewModel from data
    

【讨论】:

以上是关于Knockout JS - 在没有 ko.mapping 的情况下观察数组的任何属性中的突变的主要内容,如果未能解决你的问题,请参考以下文章

Knockout JS映射插件没有初始数据/空表单

Typescript 和 Knockout.js

knockout.js:更新绑定?

Knockout.js ko.mapping.toJS 在我看来没有刷新数据

Select2 与 Knockout.js 初始值

Knockout Js模板不显示数据