2

我有一个收藏self.models。我还有一个对象数组,其中包含我希望应用于我的集合的字段和过滤器,称为filterArr. 这方面的一个例子是:

[{field: "Account", filter: "123"}, {field: "Owner", filter: "Bob"}]

问题是,我不太确定如何遍历每个模型以仅返回那些也filterArr适用的模型,我知道它必须是这样的,但这是硬编码的:

self.models = _.filter(self.models, function (model) {
                    model = model.toJSON();
                    return model.Account === "123" && model.Owner === "Bob";

});
4

2 回答 2

7

首先,下划线的过滤器返回一个Array,所以你在这里有效地做的是用一个过滤的数组替换你的集合。像这样的东西会更合适:

this.filtered = _.filter(this.models, ...);

Backbone Collection 实现了underscore 的大部分有用功能。因此,上面的解决方案远非最佳(实际上它并不能完全按照您想要的方式工作),而是执行以下操作:

this.filtered = this.models.filter(function() {...});

到目前为止,按名称获取和设置模型字段的最佳方法是 Backbone的getset 函数Model,那么为什么不使用它们呢?Model.toJSON()有效,但您只是在attributes不必要地复制 -hash。

this.filterObj = { // Why not make it an object instead of array of objects
  "Account": "123",
  "Owner": "Bob"
};
this.filtered = this.models.filter(function(model) {
  // use the for in construct to loop the object
  for (filter in filterObj) {
    // if the model doesn't pass a filter check, then return false
    if (model.get(filter) !== filterObj[filter]) return false;
  }
  // the model passed all checks, return true
  return true;
});

希望这可以帮助!

于 2012-08-30T09:32:56.923 回答
-2

基本上,您需要遍历模型的属性并将它们的键和值与过滤器的属性进行比较。

self.models = _.filter(self.models, function (model) {
  var fits = true; // does this model "fit" the filter?
  model = model.toJSON();
  _.each(model, function(modelVal, modelKey) {
     _.each(filterArr, function(filter) {
        if (modelKey === filter.field && modelVal !== filter.filter) {
           fits = false
        }
     }
  })
  return fits
})

然而,有一点下划线魔法有一个更棘手的方法。我不确定它在性能方面是否更好,但在我看来它肯定看起来更好。

    // change a bit the way filter is described:
var filter = {Account: '123', Owner: 'Bob'},
    // save an array of filter keys (Account, Owner)
    filterKeys = _.keys(filter),
    // and an array of its values (123, Bob)
    filterVals = _.values(filter)
self.models = _.filter(self.models, function (model) {
      // pick a subset of model which has the same keys as filter
  var filteredSubset = _.pick(model.attributes, filterKeys),
      // pick values of this subset
      subsetValues = _.values(filteredSubset)
      // this values have to be equal to filter's values
      // (use .join() to turn array to string before comparison due to references)
      return filteredVals.join() === subsetValues.join()
})

请注意,在后一种情况下,所有模型都必须在过滤器中声明所有键。

如果我是你并且我正在寻找一种最稳健的方法,我会重写第一个示例,但会更改_.each为标准for循环并false在满足第一个“不合适”值时立即返回。

于 2012-08-30T09:28:01.307 回答