Knockout JS - 在没有 ko.mapping 的情况下观察数组的任何 属性 中的突变
Knockout JS - observing a mutation in any property of an array without ko.mapping
在我的应用程序中,我必须只显示一长串评分最高的前 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);
change one键是模拟长数组变化,reset键是将数组重置为初始状态
当然可以,但最简单的方法是在进行敲除之前过滤数据。如果您只关心前 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
}
}
在我的应用程序中,我必须只显示一长串评分最高的前 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);
change one键是模拟长数组变化,reset键是将数组重置为初始状态
当然可以,但最简单的方法是在进行敲除之前过滤数据。如果您只关心前 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
}
}