根据多个模型属性过滤主干集合

时间:2014-07-30 14:44:11

标签: javascript backbone.js backbone-collections backbone-model

我想要过滤骨干集合,所以返回给我的只是匹配或接近某些搜索参数的模型,

我的模型结构如下所示,

{  
    email: "name@domain.com",
    first_name: "Name",
    surname: "LastName",
    handle: "NameLastName",
    initials: "NL"  
}

上面的模型是“User”模型,它可以在“UsersCollection”中,我希望可以实现的,就是根据电子邮件地址,名字,姓氏和句柄搜索“UsersCollection”模型,此刻,我只能根据一个属性进行搜索,下面是“UsersCollection”中的搜索功能,

search : function(letters){
    if(letters == "") return this;

    var pattern = new RegExp(letters,"gi");
    return _(this.filter(function(data) {
        return pattern.test(data.get("first_name"));
    }));
}

letters参数来自视图,它们是文本输入的值。现在这可行,但它只根据first_name创建匹配,我如何匹配多个属性?

3 个答案:

答案 0 :(得分:0)

现在它将返回与任一属性匹配的模型。

  var UsersCollection = Backbone.Collection.extend({
      model: User,

      myFilter: function( email, first_name, surname , handle) {
        filtered = this.filter(function(user) {
          return user.get("email") === email || user.get("first_name") === first_name ||
                 user.get("surname") === surname || user.get("handle") == handle ;
          });
        return new UsersCollection(filtered);
      }

    });

    var filterdMe = UsersCollection.myFilter("ada@ff.d","something1","something2","something3");

答案 1 :(得分:0)

我也做类似的事情。我将input属性映射到模型键,并将对象传递给具有用户正在搜索的属性的searchsearch函数有点像这样:这是minimal jsbin demo

var Collection = Backbone.Collection.extend({
  model:yourModel,

  search:function(find) {
    return this.filter(function(model) {
      var json = model.toJSON();

      for (var k in find) {
        var re = new RegExp(find[k],"i");
        if (json[k].search(re) === -1) return false;
      }

      return true;
    });

   }
});

html代码如下:

<input name="first_name"/>
<input name="last_name"/>
<input name="email"/>

视图代码(或多或少):

var View = Backbone.View.extend({
  template:_.template($('#view-template').html()),
  events: {
    'keyup input' : 'search'
  },

  search:function() {
    var find = {};

    this.$('input').each(function() {
      var $element = $(this),
          modelKey = $element.attr('name'),
          modelVal = $element.val();
      find[modelKey] = modelVal;
    });

    var results = this.collection.search(find);

    /* do something with results */

  }
});

如果您没有大型数据集,这似乎可以正常工作。如果您不想使用indexOf对象,也可以使用toLowerCaseRegExp。也许这会让你开始走上一条道路。

答案 2 :(得分:0)

我知道这是旧的。我今天解决了同样的问题,并认为我应该发布我正在使用的代码。我从另一个stackoverflow问题中发现了很多这个问题。我现在找不到了,抱歉!

这将从骨干集合中创建一个新的数组。如果您想要另一个骨干集合,可以new BackboneCollection(search_results);

var search_results = this.collection.filter(function(model) {
  return _.some(model.attributes, function(val, attr) {

    if(val !== null && val !==  undefined)
    {
      if(!_.isString(val))
      //if a model's attribute is a number, we make it a string.
      {
        val = val.toString();
      }
      //convert both options to uppercase for better searching ;)
      val = val.toUpperCase();
      q = q.toUpperCase(); //q is the search term, I grabbed it using JQuery

      var array = q.split(" ");
      return ~val.indexOf(q);
    }
    else
    {
      return false;
    }

  });
});

注意:这不适用于多个单词。如果你正在寻找汽车大众汽车将会工作,但1988年大众汽车除非其中一个型号的属性是&#34; 1988 Volkswagen&#34;但他们更可能是两个不同的属性(年和制造)。