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

时间:2018-04-13 14:37:40

标签: memory knockout.js knockout-mapping-plugin

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

长列表是一个数组,我已经变成了一个可观察数组,所有元素都是带有ko.mapping的observable,前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 个答案:

答案 0 :(得分: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
    }
}