我最終通過延長淘汰賽觀察到陣列創建一個分類觀察到的數組:
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.push([5,2]); // sortedArray will now be [1,2,4,5,7]
sortedArray.sort(function (a,b){
return b - a;
}); // sortedArray will now be [7,5,4,2,1]
sortedArray.push(6); // sortedArray will now be [7,6,5,4,2,1]
我唯一的問題是,重新初始化時使用新數組排序的observable數組的方式與重新初始化可觀察數組的排序後的observable數組沒有進行排序相同。爲了解決這個問題,我在已排序的可觀察陣列上添加了一個重新初始化函數:
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' – Serjio 2013-08-21 07:02:22
@Serjio - 即使單線程代碼也需要關注重入。調用'sortedArray.sort'將會觸發對'sortedArray.notifySubscribers()'的另一次調用,它將以遞歸方式再次調用我們的訂閱回調。 – Brandon 2013-08-22 01:55:27
是的,我明白了。謝謝 – Serjio 2013-08-22 09:17:56