2014-03-06 26 views
4

我有一個非常簡單的textbox在某些無序的li上過濾ng-repeat。當我向textbox添加值時,null值的項目被刪除,即使清除textbox也不返回。我有一個想法爲什麼這種情況正在發生(搜索對象現在有一個空的屬性,它不匹配nulls),但我無法弄清楚如何解決問題。我試圖pop()財產關閉的搜索對象沒有運氣。Angular:在過濾器參數爲空時重新包含空值

HTML:

<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> 

JS:

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

請檢出JSfiddle更好地說明這個問題。

回答

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可以阻止用戶在單個空間上進行過濾,但到目前爲止,這似乎不會對我造成任何問題。

獎金:!將返回所有null值和!!將返回所有不null值。

0

您將無法使用filter:search。查看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; 
    } 
+0

感謝您的輸入!我很快就會嘗試。然而,是否可能以某種方式「undefine」$ scope.search.age',以便像初始加載一樣運行? – Jesse

+1

你可以'刪除$ scope.search.age',但我不確定你會如何在正確的時間完成這項工作? –

+0

我剛剛發現了'delete'!我發佈了實現該解決方案的答案。 – Jesse

3

我發現是寫一個自定義指令修改輸入字段行爲像這樣的乾淨的解決方案:

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

修改輸入NG-模型:

<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