【问题标题】:Filter for number range : AngularJS过滤数字范围:AngularJS
【发布时间】:2014-07-21 07:08:53
【问题描述】:

我有一个包含一些输入类型的表单,例如文本、收音机等。当我提交表单时,它会在表单下方列出输入的详细信息(为此使用了模板和指令)。我想在 age 中进行过滤,即数字输入类型,这样当我给出一个年龄范围时,它应该过滤具有相应年龄范围的配置文件。这是plunker:

http://plnkr.co/edit/h8p8rtZuAhCoKClUjgE9?p=preview

    <table border="1" style="width:200px">
   <tr>
       <td> <div>Name : {{  formElement.name }} </div><br> </td> 
   </tr>
   <tr>
       <td> <div>Age : {{ formElement.age }}</div><br> </td>
   </tr>

【问题讨论】:

  • 您需要对ngRepeat 使用过滤器。因此,您需要找到一种在指令之间共享filterModel 对象的方法(使用父范围或服务)。但请注意,将过滤逻辑与过滤器适用的显示逻辑分开是非常不寻常的。将过滤相关的内容放在fasterDisplay 指令中会更好。

标签: angularjs angularjs-directive angularjs-scope angularjs-ng-repeat angularjs-filter


【解决方案1】:

您可以编写一个自定义过滤器函数,按特定字段的范围进行过滤:

$scope.byRange = function (fieldName, minValue, maxValue) {
  if (minValue === undefined) minValue = Number.MIN_VALUE;
  if (maxValue === undefined) maxValue = Number.MAX_VALUE;

  return function predicateFunc(item) {
    return minValue <= item[fieldName] && item[fieldName] <= maxValue;
  };
};

并在ng-repeat表达式中使用它:

<div ng-repeat="formElement in formElements | filter:byRange('age', filterModelMin.age, filterModelMax.age)">

注意filterModelMin.agefilterModelMax.age 可以直接在fasterDisplay 指令中使用,因为fasterFormfasterDisplay 都没有自己的范围。

示例插件: http://plnkr.co/edit/dFbBCKxSxm9RI9dwSeYR?p=preview

【讨论】:

  • 如果我有一个包含所有过滤器的对象,我可以使用此功能吗?我正在编写一个应用程序,我必须在其中过滤位置和年龄范围,可能还有更多过滤器。我该怎么做呢?我的对象看起来像这样:$scope.eventsfilter = {minAge: &lt;numberrange&gt;, maxAge: &lt;numberrange&gt;, postal: &lt;string&gt;} - 所以 minAge 和 maxAge 都应该与用户定义的范围相匹配。 (因此,如果用户想要过滤 21-27 岁的事件,它也会匹配 22-24 岁的事件)。
【解决方案2】:

您可以使用自定义过滤器选择功能来做到这一点。在您的重复中,您可以这样做:

<div  ng-repeat = "formElement in formElements | filter:filterAge">

您的控制器中的以下功能:

$scope.filterAge = function(val) {
  return (val.age > MIN_AGE && val.age < MAX_AGE);
};

但是,在您的情况下,您在不同的指令和不同的范围内拥有所需的值(MIN_AGEMAX_AGE)。您可以通过使用服务或将值存储在父范围中并将引用传递给您的指令来将这些值共享给正确的指令。

【讨论】:

    【解决方案3】:

    扩展 runTarm 的答案。这将允许您使用带有点运算符的嵌套值:

    $scope.byRange = function (fieldName, minValue, maxValue) {
      if (minValue === undefined) minValue = Number.MIN_VALUE;
      if (maxValue === undefined) maxValue = Number.MAX_VALUE;
    
      return function predicateFunc(item) {
        var keys = fieldName.split('.');
        var val = item;
        for (var i = 0; i < keys.length; i++) {
          val = val[keys[i]];
        }
    
        return minValue <= val && val <= maxValue;
      };
    };
    

    像这样在你的 ng-repeat 表达式中使用:

    <div ng-repeat="formElement in formElements | filter:byRange('person.age', filterModelMin.age, filterModelMax.age)">
    

    【讨论】:

      【解决方案4】:

      这是我的解决方案,这个解决方案效果更好,因为在删除 min 和 maxlikes 输入后,所有集合都将返回。

      $scope.byRange = function (fieldName, minLikes, maxLikes) {
                          if (minLikes === undefined || maxLikes === undefined || maxLikes === null || minLikes === null) {
                              return function predicateFunctionTwo(item) {
                                  return item[fieldName];
                              }
                          } else {
                              return function predicateFunc(item) {
                              return minLikes <= item[fieldName] && item[fieldName] <= maxLikes;
                            };
                        }
                      }
      &lt;div class="content" ng-repeat="data in addingPlaceService | filter:byRange('likes', minLikes, maxLikes) track by $index"&gt;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-06
        • 2015-09-13
        • 2016-08-20
        • 2014-05-21
        • 1970-01-01
        • 2011-10-21
        • 2014-12-30
        • 2013-04-23
        相关资源
        最近更新 更多