Javascript knockout.js排序可观察数组
我希望有一个可观察的数组,当一个对象被推入其中时,它会对自身进行排序(如果它在比较器函数中使用的任何值被更改,它会对自身进行排序,这会更好) 您可以定义希望数组排序的比较器函数,然后每次调用push时,它都会将被推的对象添加到数组中的正确位置,以便数组保持排序,如:Javascript knockout.js排序可观察数组,javascript,knockout.js,Javascript,Knockout.js,我希望有一个可观察的数组,当一个对象被推入其中时,它会对自身进行排序(如果它在比较器函数中使用的任何值被更改,它会对自身进行排序,这会更好) 您可以定义希望数组排序的比较器函数,然后每次调用push时,它都会将被推的对象添加到数组中的正确位置,以便数组保持排序,如: var sortedArray = ko.sortedObservableArray( function (a,b) { return b - a;}, [1,7,4] ); // sortedArray will
var sortedArray = ko.sortedObservableArray(
function (a,b) { return b - a;},
[1,7,4]
); // sortedArray will be [1,4,7]
sortedArray.push([5,2]); // sortedArray will now be [1,2,4,5,7]
是否有任何库可以为我做到这一点?如果没有,实现这一点的最佳方法是什么?尝试以下方法:
var sortedArray = ko.observableArray();
sortedArray.subscribe(function () {
if (!sortedArray._isSorting) {
sortedArray._isSorting = true;
sortedArray.sort(function (a, b) { return b - a; });
sortedArray._isSorting = false;
}
});
您可以将其封装在一个函数中,以便在需要时创建新的排序可观察数组。我通过扩展敲除可观察数组创建了一个排序可观察数组:
ko.sortedObservableArray = function (sortComparator, initialValues) {
if (arguments.length < 2) {
initialValues = [];
}
var result = ko.observableArray(initialValues);
ko.utils.extend(result, ko.sortedObservableArray.fn);
delete result.unshift;
result.sort(sortComparator);
return result;
};
ko.sortedObservableArray.fn = {
push: function (values) {
if (!$.isArray(values)) {
values = [values];
}
var underlyingArray = this.peek();
this.valueWillMutate();
underlyingArray.push.apply(underlyingArray, values);
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
sort: function (sortComparator) {
var underlyingArray = this.peek();
this.valueWillMutate();
this.sortComparator = sortComparator;
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
reinitialise: function (values) {
if (!$.isArray(values)) {
values = [values];
}
var underlyingArray = this.peek();
this.valueWillMutate();
underlyingArray.splice(0, underlyingArray.length);
underlyingArray.push.apply(underlyingArray, values);
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
reverse: function () {
var underlyingArrayClone = this.peek().slice();
underlyingArrayClone.reverse();
return underlyingArrayClone;
}
};
var sortedArray = ko.sortedObservableArray(
function (a,b) { return a - b;},
[1,7,4]
); // sortedArray will be [1,4,7]
sortedArray([3,2,8]); // this doesn't work correctly, sortedArray will be [3,2,8]
// instead of [2,3,8]
// To get around this you can use reinitialise()
sortedArray.reinitialise([3,2,8]); // sortedArray will be [2,3,8]
我唯一的问题是,当用新数组重新初始化排序后的可观察数组时,与重新初始化可观察数组的方式相同,排序后的可观察数组没有被排序。为了解决这个问题,我在排序的可观察数组上添加了一个重新初始化函数:
ko.sortedObservableArray = function (sortComparator, initialValues) {
if (arguments.length < 2) {
initialValues = [];
}
var result = ko.observableArray(initialValues);
ko.utils.extend(result, ko.sortedObservableArray.fn);
delete result.unshift;
result.sort(sortComparator);
return result;
};
ko.sortedObservableArray.fn = {
push: function (values) {
if (!$.isArray(values)) {
values = [values];
}
var underlyingArray = this.peek();
this.valueWillMutate();
underlyingArray.push.apply(underlyingArray, values);
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
sort: function (sortComparator) {
var underlyingArray = this.peek();
this.valueWillMutate();
this.sortComparator = sortComparator;
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
reinitialise: function (values) {
if (!$.isArray(values)) {
values = [values];
}
var underlyingArray = this.peek();
this.valueWillMutate();
underlyingArray.splice(0, underlyingArray.length);
underlyingArray.push.apply(underlyingArray, values);
underlyingArray.sort(this.sortComparator);
this.valueHasMutated();
},
reverse: function () {
var underlyingArrayClone = this.peek().slice();
underlyingArrayClone.reverse();
return underlyingArrayClone;
}
};
var sortedArray = ko.sortedObservableArray(
function (a,b) { return a - b;},
[1,7,4]
); // sortedArray will be [1,4,7]
sortedArray([3,2,8]); // this doesn't work correctly, sortedArray will be [3,2,8]
// instead of [2,3,8]
// To get around this you can use reinitialise()
sortedArray.reinitialise([3,2,8]); // sortedArray will be [2,3,8]
你不需要额外的旗帜。JavaScript是一种只有一个执行行的语言,没有线程。因此,这意味着在排序过程中,
observableArray
的值不能改变operation@Serjio-即使是单线程代码也需要关注可重入性。调用sortedArray.sort
将触发另一个调用sortedArray.notifySubscribers()
,该调用将再次递归调用我们的订阅回调。是的,我明白了。谢谢