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, ...);

バックボーンコレクションは、アンダースコアの便利な機能のほとんどを実装しています。したがって、上記の解決策は最適とはほど遠いです(実際、希望どおりに機能しません)。代わりに、次のようにします。

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

モデルフィールドを名前で取得および設定するための最良の方法は、Backboneのgetandset 関数Modelです。では、それらを使用してみませんか?動作しますが、 -hashを不必要にModel.toJSON()コピーしているだけです。attributes

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 に答える