简体   繁体   English

Backbone.js过滤集合中的任何值

[英]Backbone.js filter on any value in a collection

I have a search/filter field that I would like to be able to filter on any value of the collection. 我有一个搜索/过滤字段,我希望能够过滤集合的任何值。 The data I have is as follows: 我的数据如下:

 exports.administrators = [
{
  id: 1,
  firstName: "User1",
  lastName: "Tester",
  phone: "781-000-0000",
  email: "user1.tester@email.com",
  privileges: "view-only"
}, {
  id: 2,
  firstName: "Mickey",
  lastName: "Mouse",
  phone: "781-123-4567",
  email: "mickey.mouse@disney.com",
  privileges: "all"
}, {
  id: 3,
  firstName: "Snow",
  lastName: "White",
  phone: "781-890-1234",
  email: "snow.white@disney.com",
  privileges: "all"
}, {
  id: 4,
  firstName: "Anakin",
  lastName: "Skywalker",
  phone: "888-874-9084",
  email: "anakin.skywalker@deathstar.com",
  privileges: "view-only"
}, {
  id: 5,
  firstName: "Obi-one",
  lastName: "Kenobi",
  phone: "908-765-5432",
  email: "obi.kenobi@jedi.com",
  privileges: "all"
}, {
  id: 6,
  firstName: "Master",
  lastName: "Yoda",
  phone: "876-654-2134",
  email: "yoda@jedi.com",
  privileges: "view-only"
}, {
  id: 7,
  firstName: "Han",
  lastName: "Solo",
  phone: "781-456-3209",
  email: "han.solo@gmail.com",
  privileges: "all"
}, {
  id: 8,
  firstName: "Neo",
  lastName: "TheOne",
  phone: "781-000-0000",
  email: "neo@matrix.com",
  privileges: "all"
}];

The View will fire an event based on the keyup event: View将根据keyup事件触发事件:

AdministratorView.prototype.events = {
  'click .sub-content th.sort, .sub-content th.sort-up, .sub-content th.sort-down': 'sortTable',
  'click .light-btn': 'showAdd',
  'keyup #filter-find': 'filterAdministrators'
};

I have also abstracted the function that I want to perform the filtering: 我还抽象了我想要执行过滤的功能:

  App.Utils.filterCollection = function(collection, filterValue) {
if (filterValue !== "") {
  return _.filter(collection.models, function(data) {
    var values;
    values = _.values(data.attributes);
    _.each(values, function(value) {
      if (!isNaN(value)) {
        value = value.toString();
      }
      return value.indexOf(filterValue) > 0;
    });
  });
}

}; };

The problem I have is: 我遇到的问题是:

  1. The filterCollection function is returning undefined filterCollection函数返回undefined
  2. Is there a more elegant way of doing this? 有更优雅的方式吗?

Thanks for all the help in advance. 在此先感谢您的所有帮助。

Cheers, 干杯,

Kianosh Kianosh

Updated function: 更新功能:

I have updated the function with some input from @dbaseman 我用@dbaseman的一些输入更新了这个函数

  App.Utils.filterCollection = function(collection, filterValue) {
var filteredCollection;
if (filterValue === "") {
  [];
}
return filteredCollection = collection.filter(function(data) {
  return _.some(_.values(data.toJSON()), function(value) {
    value = !isNaN(value) ? value.toString() : value;
    return value.indexOf(filterValue) >= 0;
  });
});

}; };

However I am still getting an empty (or undefined) value from the function. 但是我仍然从函数中获取一个空(或未定义)值。 I am stomped!! 我被踩!!

Update #2 Found a partial solution. 更新#2找到了部分解决方案。 Here is the jsFiddle - http://jsfiddle.net/kianoshp/YWSSp/ . 这是jsFiddle - http://jsfiddle.net/kianoshp/YWSSp/ It filters correctly, however when I blank out the filter field I expect the original data set to be displayed. 它正确过滤,但是当我清空过滤器字段时,我希望显示原始数据集。 However now I get a blank table. 但是现在我得到一张空白的桌子。 Working on solution but any help/hint would be helpful. 解决方案,但任何帮助/提示都会有所帮助。

Update #3 Final solution is here in the jsFiddle --> http://jsfiddle.net/kianoshp/YWSSp/77/ thanks to @dbaseman 更新#3最终解决方案在jsFiddle中 - > http://jsfiddle.net/kianoshp/YWSSp/77/感谢@dbaseman

I don't think there's a more elegant way, except for minor improvements: 除了微小的改进之外,我认为没有更优雅的方式:

  1. Backbone collections proxy to Underscore.JS methods, so you can use collection.filter Backbone集合代理Underscore.JS方法,因此您可以使用collection.filter
  2. Yould also use _.some to check if any value matches 你还可以使用_.some检查是否有任何值匹配

As far as problems, there are two as far as I could tell: 就问题而言,据我所知,有两个问题:

  1. You're calling _.values on a Backbone model (that's what filter returns when called on a Backbone collection). 你在Backbone模型上调用_.values (这是在Backbone集合上调用时返回的filter )。 You have to call filter on the JSON representation, using model.toJSON() . 您必须使用model.toJSON()在JSON表示上调用filter。
  2. You're checking if the value is a number , but then calling indexOf on the value. 您正在检查该值是否为数字 ,但随后在该值上调用indexOf I think you meant to check if it's a string (`typeof value == 'string'). 我想你的意思是检查它是否是一个字符串 (`typeof value =='string')。

Here's the modified function ( Demo ). 这是修改后的功能( Demo )。

Backbone.Collection.prototype.filterValues = function(filterValue) {
    if (filterValue == "") return [];
    return this.filter(function(data) {
        return _.some(_.values(data.toJSON()), function(value) {
           if (_.isNumber(value)) value = value.toString();
           if (_.isString(value)) return value.indexOf(filterValue) != -1;
           return false;
        });
    });
}

I've taken the answer McGarnagle provided and added some improvements. 我已经接受了McGarnagle提供的答案并添加了一些改进。 The below code allows you to search inside Models that have properties consisting of objects. 下面的代码允许您在具有包含对象的属性的模型内搜索。

Backbone.Collection.prototype.filterValues = function(filterValue) {
if (filterValue === ""){
    return this.models;
}

function collectionFilter(data) {
    if(data.toJSON){
        data = data.toJSON();
    }

    return _.some(_.values(data), function(value) {
        if(_.isObject(value)){
            return collectionFilter(value);
        }

        if (_.isNumber(value)){
            value = value.toString();
        }

        if (_.isString(value)){
            value = value.toLowerCase();

            return value.indexOf(filterValue) !== -1;
        }

        return false;
    });
}

return this.filter(collectionFilter);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM