取消选中大型(1000)数据集上的复选框时,淘汰赛很慢 [英] Knockout is slow when unchecking checkboxes on a large (1000) dataset

查看:23
本文介绍了取消选中大型(1000)数据集上的复选框时,淘汰赛很慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码来检查我视图中的所有复选框.

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"

我现在删除了一些不必要的"可观察对象,对于最有可能不会改变的属性,它的行为会稍微好一些,但仍然很慢,尤其是在 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.

checked 绑定可以处理选定项的数组,但仅支持在数组中存储字符串.我使用支持在数组中存储对象的自定义绑定(如 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 }" />

选择所有项目的复选框使用正常的checked绑定并附加到可写的计算可观察对象:

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)数据集上的复选框时,淘汰赛很慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆