我使用这段代码来选中视图中的所有复选框。
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秒。奇怪的是,当过滤的结果很小时,它仍然需要更长的时间,即使过滤的结果从1000个总数中大约为40个。
复选框在表中,使用databind="foreach:contents"绑定
我现在已经删除了一些"不必要的"可观测性,对于最有可能不会改变的属性,它的性能会稍微好一点,但仍然非常慢,尤其是在firefox中。最大的问题是,为什么这种行为只针对取消复选框,而不针对过滤、排序、检查等。
注意:它只会取消选中复选框,基本上当"选中"为false时,否则它会很快。
编辑:我一次只显示50个项目,但我正在检查/取消检查所有筛选的项目。这样,我就可以控制发布到服务器的内容。
这就是我在这个场景中使用的。也许它会对你有所帮助。
checked
绑定可以处理选定项的数组,但仅支持在数组中存储字符串。我使用了一个自定义绑定,它支持在数组中存储对象(就像selectedOptions
一样):
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;
}
};
每个复选框的绑定如下所示:
<input type="checkbox" data-bind="checkedInArray: { array: $parent.selectedItems, value: $data }" />
用于选择所有项目的复选框使用正常的checked
绑定,并附加到可写的计算可观察:
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
绑定选项,使上述自定义绑定变得不必要。您现在可以像这样绑定复选框:
<input type="checkbox" data-bind="checked: $parent.selectedItems, checkedValue: $data" />
示例:http://jsfiddle.net/mbest/RLLX6/
如果使用jQuery选中/取消选中所有框,性能会发生什么变化?
$('#tableId').find('input[type=checkbox]').prop('checked', checked);
或者,你可以在显示所有框时选中它们,而不是一次完成所有框吗?
此外,您可以尝试使用knockout.utils方法来过滤可观察的数组,我很想看看是否有任何性能差异。
var filteredArray = ko.utils.arrayFilter(this.items(), function(item) {
return ko.utils.stringStartsWith(item.name().toLowerCase(), filter);
});
还有一种在数组上循环并处理每个元素的方法:
ko.utils.arrayForEach(this.items(), function(item) {
var value = parseFloat(item.priceWithTax());
if (!isNaN(value)) {
total += value;
}
});
再说一次,我不知道这是否有助于提高性能,尽管我认为这在美观方面要好一点!