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% 的时间)我必须对它们执行加法操作。我真的不想创建第二个 ko.computed 函数,因为每次执行搜索时我都必须第二次遍历这个数组。

所以,我的问题是:有没有办法可以使用相同的 ko.computed 来创建第二个不匹配项的数组?基本上遍历数组并将每个项目放入匹配或不匹配的数组中......

如果没有,是否更快:1)创建第二个 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 回答