【问题标题】:AngularJS, accessing ngRepeat values in filter predicateAngularJS,在过滤谓词中访问 ngRepeat 值
【发布时间】:2017-06-13 03:55:54
【问题描述】:

我在寻找解决方案方面的最佳尝试都是徒劳的。基本上我想在我的 html 中做这样的事情:

    <div data-ng-repeat="tag in allTags">
  <h3>{{tag}}</h3>
  <uib-accordion>
    <div uib-accordion-group data-ng-repeat="item in displayItems | filter: tagFilter: tag">

tagFilter 看起来像这样:

  $scope.tagFilter = function(item, tag) {
    if(item.tags.indexOf(tag) === -1) {
      return false;
    }
    return true;
  }

displayItems 中的每个项目都是一个具有标签数组的对象,因此显示项目看起来像这样:

[
{ title: "Item 1 Title", body: "Some escaped HTML Content", tags: ["tag1", "tag2", "tag3"]}, 
{ title: "Item 2 Title", body: "Some escaped HTML Content", tags: ["tag2", "tag4"] }
]

我希望它出现在它所属的所有标题下。问题是我不知道如何正确地将'tag'的值传递给tagFilter。在上面的代码中codeFilter中的参数标签无论如何都等于0。

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    这里的问题实际上出在过滤器语法的语义上。更具体地说,您在上面使用的语法是在您使用 ngApp.filter(...) 语法定义 Angular 过滤器时使用的......即,为整个应用程序注册的过滤器,可以在任何地方使用。在这种情况下,过滤器语句中的第三个参数是您要传递给已注册过滤器的值。

    在您的情况下,您在控制器中定义了一个过滤器function,它改变了过滤器的工作方式。具体来说,您不能将动态值传递给控制器​​内的过滤器函数。当您将函数用作filter 表达式时,它具有以下签名:

    function(value, index, array) {}

    然后在 filter 语句中仅通过函数名调用,所以:

    array|filter:filterfunction - 没有参数或括号。

    value 是被过滤的当前项目(在数组中)的值,index 是该项目在数组中的索引,array 是被过滤的整个数组。您不能将值“传递”给此表达式,但如果适用,您可以使用控制器或范围变量。在您的情况下,这不是因为您要过滤的值在中继器内。

    要实现您想要的,您需要将您的$scope.tagFilter 变成一个实际的 Angular 过滤器,如下所示:

    ngApp.filter('tagFilter', function($filter)
    {
            return function(items, searchValue)
            {   
                // initialize array to return
                var filtered = [];
    
                angular.forEach(items, function(obj)
                {
                   // use filter to find matching tags (3rd param means EXACT search - set to False for wildcard match)
                   var objFilter = ($filter("filter")(obj.tags, searchValue, true))[0];
    
                   // If a matching tag was found, add it to the filtered array
                   if (objFilter) filtered.push(obj);
                });
    
                return filtered;
            };
        });
    

    以上假设您已将angular.module(...) 引导程序保存到名为ngApp 的变量中。注册此过滤器后,您当前的过滤器语法应该可以按预期工作!

    【讨论】:

    • 不幸的是,它似乎没有帮助,行为和以前完全一样
    • 那么需要查看更多您的用例。如果“displayItems”是一个对象而不是一个数组,那么它就不起作用——否则它应该起作用。您可以发布您的数据点的样子吗?也可能想尝试分配 tagFilter 并且您的数据指向控制器变量,而不是使用 $scope。就我个人而言,我不再使用 $scope 变量,只是因为 ng-if 和其他可能导致 $scope 分配的变量无法访问的指令的细微差别。
    • 添加了 displayItems 的外观示例(它最初是从服务器检索的 JSON 数据)。我已经通过开发工具进行了检查,它被正确地引入和解释了。
    【解决方案2】:

    假设 displayItems 是一个数组,

    <div uib-accordion-group data-ng-repeat="item in displayItems.filter(tagFilter(tag))" >
    

    应该可以解决问题。

    【讨论】:

    • 这导致我的 tagFilter 函数中的“项目”被传递标签的值,并且标签未定义。我尝试改为 displayItems.filter(tagFilter(item, tag)) 之后标签正确且项目未定义。
    【解决方案3】:

    根据这篇博文找到了一种方法:https://toddmotto.com/everything-about-custom-filters-in-angular-js/

    基本上我必须创建自己的自定义过滤器,而不是使用 angulars 谓词过滤器

    Javascript:

      ng.module('faq').filter(
        'tagFilter', function() {
          return function(items, tag) {
            return items.filter(function(item) {
              if(item.tags.indexOf(tag) === -1) {
                return false;
              }
              return true;
            });
          }
        }
      )
    

    HTML:

    <div uib-accordion-group data-ng-repeat="item in displayItems | tagFilter: tag">
    

    仍然不知道为什么原始版本不起作用,所以如果有人能回答那 10 分给他们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      • 2010-11-30
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多