Angular:当filter参数为空时重新包含空值

时间:2014-03-06 20:44:17

标签: angularjs

我在一些无序textbox上过滤ng-repeat非常简单li。当我向textbox添加值时,具有null值的项目将被删除,即使清除textbox也不会返回。我知道为什么这种情况发生(搜索对象现在有一个与nulls不匹配的空属性),但我无法弄清楚如何解决问题。我试图pop()搜索对象的<div ng-controller="ListCtrl"> <input type="text" ng-model="search.age" placeholder="Age"></input> <ul> <li ng-repeat="item in items | filter:search"> {{item.name}} - {{item.age}} </li> </ul> </div> 没有运气。

HTML:

function ListCtrl($scope) {
  $scope.items = [
    {'name':'Carl', 'age':69},
    {'name':'Neil', 'age':54},
    {'name':'Richard'},
    {'name':'Chris', 'age':58}
  ];
}

JS:

{{1}}

请结帐JSfiddle以更好地说明问题。

4 个答案:

答案 0 :(得分:4)

我在answer的帮助下想出来了。如果我只是在文本框中添加ng-change,我可以查看空值和delete属性。

HTML:

<input type="text" ng-model="search.age" ng-change="clear()" placeholder="Age"></input>

JS:

$scope.clear = function(){
    if($scope.search.age.length == 0){
        delete $scope.search.age;
    }
}

更新了fiddle。我知道当前if阻止用户在单个空间上进行过滤,但到目前为止,这似乎不会对我造成问题。

BONUS: !将返回所有null个值,而!!将返回所有null个值。

答案 1 :(得分:4)

我发现最干净的解决方案是编写一个自定义指令来修改输入字段行为,如下所示:

app.directive('deleteIfEmpty', function () {
    return {
        restrict: 'A',
        scope: {
            ngModel: '='
        },
        link: function (scope, element, attrs) {
            scope.$watch("ngModel", function (newValue, oldValue) {
                if (typeof scope.ngModel !== 'undefined' && scope.ngModel.length === 0) {
                    delete scope.ngModel;
                }
            });
        }
    };
});

使用如下:

 <input type="text" ng-model="filter" delete-if-empty>

答案 2 :(得分:2)

修改输入ng-model:

<input type="text" ng-model="searchObj.age" placeholder="Age"></input>

将此添加到您的控制器:

$scope.searchObj = {
}

其中任何一个都可以在你的html重复中使用:

ng-repeat="item in items | filter: searchObj.age"

或者

ng-repeat="item in items | filter: {age: searchObj.age || undefined}"

jsfiddle

答案 3 :(得分:0)

您将无法使用过滤器:搜索。查看Angular代码,如果您的未定义年龄的obj被过滤(即使输入为空),它将通过此​​switch语句落入并始终返回false。由于$scope.search.age未定义,因此第一次运行ng-repeat时不会调用此开关。在您第一次进入输入并清除它之后,现在$scope.search.age是一个空字符串...所以过滤器将始终运行。

  switch (typeof obj) { ***<-- obj is undefined when you have a missing age***
    case "boolean":
    case "number":
    case "string":
      return comparator(obj, text);
    case "object":
      switch (typeof text) {
        case "object":
          return comparator(obj, text);
        default:
          for ( var objKey in obj) {
            if (objKey.charAt(0) !== '$' && search(obj[objKey], text)) {
              return true;
            }
          }
          break;
      }
      return false;
    case "array":
      for ( var i = 0; i < obj.length; i++) {
        if (search(obj[i], text)) {
          return true;
        }
      }
      return false;
    default:
      return false;  ***<--falls through and just returns false***
  }

您可以尝试编写自己的过滤器功能,如下所示。

http://jsfiddle.net/wuqu2/

<div ng-controller="ListCtrl">
    <input type="text" ng-model="search.age" placeholder="Age"></input>
    <ul>
        <li ng-repeat="item in items | filter:checkAge">
            {{item.name}} - {{item.age}}
        </li>
    </ul>
</div>

  $scope.checkAge = function(item)
  {
      if($scope.search && $scope.search.age && $scope.search.age.length > 0)
      {
          return item.age && item.age.toString().indexOf($scope.search.age) > -1;
      }
      return true;
  }