【问题标题】:Check if object has multiple values based off array检查对象是否具有基于数组的多个值
【发布时间】:2016-08-16 10:17:08
【问题描述】:

解决方案

Sergio 在下面的回答效果很好,特别是他提供的 objectsMatch 函数。我还需要支持 multi-select 选择元素进行过滤,所以我稍微修改了他的功能,以防其他人正在寻找类似的功能:

function objectsMatch(roll, filterObject) {
  var match = true;
  for (var prop in filterObject) {
    if(!roll.hasOwnProperty(prop) ||
       !filterObject.hasOwnProperty(prop)) continue;
       if(Array.isArray(filterObject[prop])){
         var matchesNoValues = function(){
           for(var i = 0; i < filterObject[prop].length; i++){
             console.log(filterObject[prop][i])
             if(roll[prop] == filterObject[prop][i]){
               return false;
             }
           }
           return true;
         }
           if (matchesNoValues()  &&
                filterObject[prop] != ''
               ) {
               match = false;
               }
       }else{
         if (roll[prop] != filterObject[prop]  &&
                filterObject[prop] != ''
             ) {
             match = false;
             }
       }
    }
  return match;
}

编辑 1

我能够在 MVP here 中复制我正在寻找的功能。我现在正试图弄清楚如何将其应用于我的过滤器。希望这可以更好地展示我正在努力实现的目标。

原帖

我正在尝试添加一个自定义过滤器来过滤 Angular 表中的行。我需要检查重复中的每个对象是否具有 all 我的过滤器数组中表示的值。这些值由我的表中的 select 元素设置。

例如,我的数据集如下所示:

$scope.sushi = [
  { name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
  { name: 'Philly', fish: 'Tuna', tastiness: 4 },
  { name: 'Tiger', fish: 'Eel', tastiness: 7 },
  { name: 'Tiger', fish: 'Tuna', tastiness: 3 },
  { name: 'Rainbow', fish: 'Variety', tastiness: 62 }
];

说我的过滤器数组包含:

var filters = ['Philly', 'Tuna', 4];

它只会显示

$scope.sushi[1] 

在重复中。

然后说过滤器数组值更新为:

var filters = ['Philly', 'Tuna', 1000];

现在不会显示任何行,因为我的数据集中没有对象包含过滤器数组中的所有值。

HERE 是我迄今为止尝试过的方法的链接,两种方法分别标记为 METHOD 1METHOD 2

我想我几乎可以使用 METHOD 1,但是如果我选择对象中 的多个值,则不会显示任何行,它只会显示一行当我只选择 1 过滤器时。至于 METHOD 2,它只检查过滤器数组中的至少一个值是否在对象中,而不是全部。

这是我的过滤器中的完整代码:

.filter('byColumn', function(){
  return function(rolls, filterVal){
  var filtered = [];
  var test = true;
  for(var x in rolls){
    var currentRoll = rolls[x];
    for(y in currentRoll){

    // METHOD 1
    var allMatches = true;
    for(var i = 0; i < filterVal.length; i++){
      if(filterVal[i]){
        if(currentRoll[y] == filterVal[i]){
          continue;
        }else{
          allMatches = false;
          break;
        }
      }
    }
    if(allMatches){
        if (filtered.indexOf(currentRoll) == -1) {
          filtered.push(currentRoll);
        }
    }
    if(!allMatches){
      rolls = [];
    }

    // METHOD 2
    // angular.forEach(filterVal, function(filter){
    //   if(currentRoll[y] == filter){
    //     if (filtered.indexOf(currentRoll) == -1) {
    //         filtered.push(currentRoll);
    //     }
    //   }
    // });

      }
    }
        return filtered.length ? filtered : rolls;
      }
    });

代码基于 Scotch.io 找到的教程 here,我已对其进行了修改以满足我的需求。

提前感谢您的任何建议。

【问题讨论】:

    标签: javascript angularjs filter angularjs-ng-repeat angularjs-filter


    【解决方案1】:

    您可以将 columnFilter 对象而不是 filters 数组传递给 byColumn 过滤器

    看起来像这样:

    <tr ng-repeat="roll in sushi | orderBy:sortType:sortReverse | filter:searchFish | byColumn:columnFilter track by $index">
      <td>{{ roll.name }}</td>
      <td>{{ roll.fish }}</td>
      <td>{{ roll.tastiness }}</td>
    </tr>
    

    byColumn 过滤器可能如下所示:

    .filter('byColumn', function(){
        return function(rolls, filterVal){
    
       var filtered = [];
    
       for(var x in rolls){
          var currentRoll = rolls[x];
    
          if(objectsMatch(currentRoll, filterObject)) {
              filtered.push(currentRoll);
          }
       }
    
       return filtered;
      };
    })
    

    这就是 objectsMatch 函数

    function objectsMatch(roll, filterObject) {
    
        var match = true;
    
        for (var prop in filterObject) {
    
            if(!roll.hasOwnProperty(prop) ||
               !filterObject.hasOwnProperty(prop)) continue;
    
            if (roll[prop] != filterObject[prop] && filterObject[prop] != '') 
            {
                match = false;
            }
        }
    
        return match;
    }
    

    小提琴Here

    希望这对你有用!

    【讨论】:

    • 感谢您查看@Sergio,但小提琴似乎不起作用?一旦我做出选择,所有行都会消失?
    • 我认为这是理想的行为。只有匹配三个过滤器的行才会显示
    • 对不起,我想我在最初的帖子中并不清楚。我正在寻找的是如果有一个过滤器,它只显示包含该值的行。如果数组中有 2 个过滤器,它只显示具有这两个值的行。如果数组中有 3 个过滤器,则它必须包含该行中的所有 3 个值,依此类推。我添加了一个指向 MVP fiddle 的链接,以更好地展示我正在寻找的内容
    • @adrian_reimer 我更新了答案。希望它现在有所帮助
    猜你喜欢
    • 1970-01-01
    • 2021-12-10
    • 2020-05-12
    • 2018-07-01
    • 2019-03-31
    • 1970-01-01
    • 2017-01-09
    • 2013-07-03
    • 2020-06-08
    相关资源
    最近更新 更多