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

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

问题描述

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

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"

我现在删除了一些unes​​cessaryobservables,对于很可能不会出现的属性改变,然后表现稍好,但仍然很慢,特别是在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屋!

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