3

オブジェクトがプッシュされたときにそれ自体をソートする監視可能な配列が必要です(コンパレータ関数で使用していた値のいずれかが変更された場合、それ自体がソートされるとさらに良いでしょう)。

配列をソートするコンパレーター関数を定義すると、プッシュが呼び出されるたびに、プッシュされたオブジェクトが配列内の正しい場所に追加されるため、配列は次のようにソートされたままになります。

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]

私のためにこれを行うライブラリはありますか?そうでない場合、これを実装するための最良の方法は何ですか?

4

2 に答える 2

3

ノックアウトの監視可能な配列を拡張して、ソートされた監視可能な配列を作成することになりました。

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]

私が抱えている唯一の問題は、ソートされた監視可能な配列を新しい配列で再初期化するときに、監視可能な配列を再初期化するときに、ソートされた監視可能な配列がソートされていないことです。これを回避するために、ソートされた監視可能な配列に再初期化関数を追加しました。

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]
于 2013-03-08T17:51:28.233 に答える
2

これを試して:

var sortedArray = ko.observableArray();
sortedArray.subscribe(function () {
    if (!sortedArray._isSorting) {
        sortedArray._isSorting = true;
        sortedArray.sort(function (a, b) { return b - a; });
        sortedArray._isSorting = false;
    }
});

これを関数にまとめて、必要なときにいつでも新しい並べ替えられた監視可能な配列を作成できます。

于 2013-03-04T19:43:09.573 に答える