取消选中大型(1000)数据集上的复选框时,Knockout很慢 [英] Knockout is slow when unchecking checkboxes on a large (1000) dataset
问题描述
我正在使用此代码检查我视图中的所有复选框。
I am using this code, to check all checkboxes on my view.
var checked = self.includeAllInSoundscript();
var contents = self.filterContents(self.getFilters());
for (var i = 0; i < contents.length; i++) {
contents[i].includeInSoundscript(checked);
}
return true;
复选框
<input type="checkbox" data-bind="checked: includeInSoundscript" title="sometitle" />
这是内容:
(function (ko) {
ContentViewModel = function (data) {
this.orderId = data.orderId;
this.contentReferenceId = ko.observable(data.contentReferenceId);
this.includeInSoundscript = ko.observable();
});
这是过滤方式:
self.getFilters = function() {
var filterOrders = $.grep(self.orders(), function (order) {
return (order.usedInfilter());
});
var filterLocations = $.grep(self.locations(), function (location) {
return (location.usedInfilter());
});
return { orders: filterOrders, locations: filterLocations };
};
self.filterContents = function (filter) {
var filteredArray = self.contents();
if (filter.orders.length > 0) {
filteredArray = $.grep(filteredArray, function (content) {
return $.grep(filter.orders, function (order) {
return (order.orderId == content.orderId);
}).length > 0;
});
}
if (filter.locations.length > 0) {
filteredArray = $.grep(filteredArray, function (content) {
return $.grep(filter.locations, function (location) {
return $.inArray(location.location, content.orderedFrom().split('/')) != -1;
}).length > 0;
});
}
return filteredArray;
};
检查所有复选框很快,但是当我取消选中时,最多可能需要20秒。奇怪的是,当文件化结果很小时,即使过滤后的结果大约为40,仍然会花费更长的时间,总计1000.
Checking all checkboxes is fast, but when i uncheck, it can take up to 20 seconds. Strange thing is when the filetered result is small, it still takes a bit longer, even if the filtered results is about 40, from a total set of 1000.
复选框是在一个表中,绑定使用data-bind =foreach:contents
The checkbox is in a table, bound using data-bind="foreach: contents"
我现在删除了一些unescessaryobservables,对于很可能不会出现的属性改变,然后表现稍好,但仍然很慢,特别是在Firefox中。最大的问题是,为什么这种行为只取消选中复选框,而不是过滤,排序,检查等。
I have now removed some of the "unescessary" observables, for properties that most likely will not change, it then behaves slightly better, but still very slow, especially in firefox. The big question is, why is this behavior only on unchecking checkboxes, and not on filtering, sorting, checking, etc.
注意:它只取消选中复选框,基本上当检查是假的,否则它很快。
Notice: Its only unchecking the checkboxes, basically when "checked" is false, otherwise its fast.
编辑:我一次只显示50个项目,但我正在检查/取消选中所有已过滤的项目。这样,我就可以控制发布到服务器的内容。
I am only displaying 50 items at a time, but i am checking / unchecking all the filtered items. This, so that I have controll over what to post to the server.
推荐答案
这就是我用于此场景的内容。也许它会帮助你。
This is what I use for this scenario. Maybe it will help you.
已检查
绑定可以使用所选项目的数组,但仅支持存储数组中的字符串。我使用支持在数组中存储对象的自定义绑定(如 selectedOptions
):
The checked
binding can work with an array of selected items, but only supports storing strings in the array. I use a custom binding that supports storing objects in the array (like selectedOptions
does):
ko.bindingHandlers.checkedInArray = {
init: function (element, valueAccessor) {
ko.utils.registerEventHandler(element, "click", function() {
var options = ko.utils.unwrapObservable(valueAccessor()),
array = options.array, // don't unwrap array because we want to update the observable array itself
value = ko.utils.unwrapObservable(options.value),
checked = element.checked;
ko.utils.addOrRemoveItem(array, value, checked);
});
},
update: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()),
array = ko.utils.unwrapObservable(options.array),
value = ko.utils.unwrapObservable(options.value);
element.checked = ko.utils.arrayIndexOf(array, value) >= 0;
}
};
每个复选框的绑定如下所示:
The binding for each checkbox then looks like this:
<input type="checkbox" data-bind="checkedInArray: { array: $parent.selectedItems, value: $data }" />
选择所有项目的复选框使用正常已选中
绑定并附加到可写的计算可观察量:
The checkbox for selecting all items uses the normal checked
binding and is attached to a writable computed observable:
this.allItemsSelected = ko.computed({
read: function() {
return this.selectedItems().length === this.items().length;
},
write: function(value) {
this.selectedItems(value ? this.items.slice(0) : [] );
},
owner: this
});
示例: http://jsfiddle.net/mbest/L3LeD/
更新: Knockout 3.0.0介绍 checkedValue
绑定选项,它不需要上面的自定义绑定。你现在可以绑定这样的复选框:
Update: Knockout 3.0.0 introduced the checkedValue
binding option that makes the above custom binding unnecessary. You can now bind the checkboxes like this:
<input type="checkbox" data-bind="checked: $parent.selectedItems, checkedValue: $data" />
示例: http://jsfiddle.net/mbest/RLLX6/
这篇关于取消选中大型(1000)数据集上的复选框时,Knockout很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!