0

ユーザーが検索を実行できるオブジェクトの配列があります。検索に基づいてko.computed関数を使用して、一致するアイテムの別の配列を作成して表示しています。

self.matchedRecords = ko.computed(function() {
  return ko.utils.arrayFilter(self.transponders(), function(r) {
    return r.title.toLowerCase().indexOf($('.search-input').val().toLowerCase()) > -1
  }
};

これはうまく機能し、これまでのパフォーマンスには本当に感銘を受けました。

この問題は、場合によっては(60%の確率で)加算操作を実行する必要があるため、「一致しない」レコードも必要になることです。2番目のko.computed関数を作成したくないのは、検索が実行されるたびにこの配列を2回実行する必要があるためです。

だから、私の質問:同じko.computedを使用して、一致しないアイテムの2番目の配列を作成する方法はありますか?基本的に配列を実行し、各アイテムを一致または不一致の配列に配置します...

そうでない場合は、次の方が高速です。1)ユーザーが検索するときに配列から一致しないアイテムを取得するために2番目のko.computedを作成します。または2)arrayDiff関数を記述し、必要に応じて一致しないアイテムをオンデマンドで判別します。

乾杯!

4

1 に答える 1

1

パフォーマンスが心配な場合は、計算結果で検索結果を反復処理するときにデータを入力する、観測不可能な配列を使用できます。また、ループ内で jQuery を使用して繰り返し選択していることにも注意してください。これにより、KO によるスローダウンが無効になると思います。

self.missedRecords = [];

self.matchedRecords = ko.computed(function() {
    var searchQuery = $('.search-input').val().toLowerCase(),
        transponders = self.transponders(),
        matched = [];

    // Clear out missed records
    self.missedRecords.length = 0;

    _.each(transponders, function(transponder) {
        if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) {
            matched.push(transponder);
        } else {
            self.missedRecords.push(transponder);
        }
    });

    return matched;
});

_.eachコードを短くするためにアンダースコアから使用しました。このアプローチの欠点は、への変更をmissedRecords(確実に) UI にバインドできないことです (たとえば、foreachバインディングがある場合)。

配列を監視可能にする必要があり、missedRecordsそれでも物事を高速に保ちたい場合は、次のようにすることができます。

self.missedRecords = ko.observableArray([]);

self.matchedRecords = ko.computed(function() {
    var searchQuery = $('.search-input').val().toLowerCase(),
        transponders = self.transponders(),
        matched = [],
        missed = [];

    _.each(transponders, function(transponder) {
        if (transponder.title.toLowerCase().indexOf(searchQuery) >= 0) {
            matched.push(transponder);
        } else {
            missed.push(transponder);
        }
    });

    // Clear out missed records, without triggering subscriptions
    self.missedRecords().length = 0;

    // Copy the local missed array to the KO observable array
    // This will NOT trigger notifications
    ko.utils.arrayPushAll(self.missedRecords(), missed);

    // Tell KO that the observable array has mutated - this will trigger changes
    // to anything observing the missedRecords array
    self.missedRecords.valueHasMutated();

    return matched;
});

また、完全にスキップcomputedして変更をサブスクライブするだけで、アレイの状態を変更することもできます。例えば:

self.missedRecords = ko.observableArray([]);
self.matchedRecords = ko.observableArray([]);

self.transponders.subscribe(function(newTransponders) {
    var matched = [],
        missed = [];

    _.each(newTransponders, function(transponder) {
        // Populate matched/missed local arrays
    });

    // Copy the arrays to the observableArray instances using the technique above
});
于 2013-02-03T00:43:59.253 に答える