I have an array of objects that I'm displaying in my Angular app using ng-repeat
. I'm filtering out items using filter
and the value of a search input. It works as expected. But, I have a "select all" / "deselect all" option and I only want to select the visibile items in the list (the ones that meet the current search criteria).
我有一个数组,我用ng-repeat在我的角化应用中显示。我用过滤器和搜索输入的值过滤掉项目。它能够正常工作。但是,我有一个“选择所有”/“取消选择所有”选项,我只想选择列表中的visibile项目(满足当前搜索条件的项目)。
Without performing the same logic in my controller (i.e. using indexOf
the search value on each of my objects), how can I tell which items are currently filtered out by ng-repeat
/filter
?
如果不在我的控制器中执行相同的逻辑(例如,在我的每个对象上使用搜索值的索引),我如何知道哪些项当前被ng-repeat/filter过滤掉?
My view:
我的观点:
<input type="text" ng-model="searchValue">
<input type="checkbox" ng-model="checkAll" ng-change="toggleAll()">
<tr ng-repeat="item in items | filter:searchValue">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
</tr>
A function in my controller:
控制器中的函数:
$scope.toggleAll() {
for(var i in $scope.items){
// how can I tell if this item is filtered out in the view?
}
}
I have significantly simplified my code samples here for simplicity since this question doesn't need much more detail. Is there a way to do what I'm thinking or do I need to perform the "search" again?
由于这个问题不需要更多的细节,为了简单起见,我在这里对代码示例进行了显著的简化。有没有一种方法可以让我做我想做的事,或者我需要再做一次“搜索”吗?
3 个解决方案
#1
17
You can bind the filtered array to another scope variable in your view, then access that in your controller.
可以将过滤后的数组绑定到视图中的另一个范围变量,然后在控制器中访问该变量。
View:
观点:
<tr ng-repeat="item in filteredItems = (items | filter:searchValue)">
...
</tr>
Controller:
控制器:
$scope.toggleAll = function () {
angular.forEach($scope.filteredItems, function (item) {
// do stuff
})
}
#2
1
Your issue is that ng-repeat is scope isolated. As a result you can't refer to the internal list that is being managed by ng-repeat from your controller/directive.
您的问题是,ng-repeat是隔离的范围。因此,您无法从控制器/指令中引用由ng-repeat管理的内部列表。
As a result there are 2 options
因此有两个选择
-
Bind the filtered list to ng-repeat from your controller/directive, so you maintain the filtered list.
将过滤后的列表从控制器/指令绑定到ng-repeat,这样就可以维护过滤后的列表。
//in your controller $scope.filteredItems = $filter('yourFilter')($scope.items,$scope.searchText); $scope.$watch('searchText', function(newValue){ $scope.filteredItems = $filter('yourFilter')($scope.items, newValue); }); //in your view <tr ng-repeat="item in filteredItems"> <td>{{item.id}}</td> <td>{{item.name}}</td> </tr>
-
Perform the filter again in your controller/directive
在控制器/指令中再次执行过滤器
$scope.toggleAll() { var items = $filter('yourFilter')($scope.items, $scope.searchText); for(var i in items){ //set your selected property } }
#3
1
Angular filters create a new array. So in order to perform an action on the filtered items you're going to have to capture the new array.
角过滤器创建一个新的阵列。为了对过滤后的项执行操作,你需要捕获新的数组。
Something like:
喜欢的东西:
$scope.toggleAll() {
var filteredItems = $filter('filter')($scope.items, $scope.searchValue);
for(var i in filteredItems) {
...
}
}
If you don't want to filter twice you'll have to filter the array yourself every time searchValue
changes and ng-repeat
over that filtered array, ng-change is useful in that case.
如果你不想要过滤两次,你必须自己过滤数组,每次searchValue的改变和ng-repeat的过滤,在这种情况下,ng-change是有用的。
#1
17
You can bind the filtered array to another scope variable in your view, then access that in your controller.
可以将过滤后的数组绑定到视图中的另一个范围变量,然后在控制器中访问该变量。
View:
观点:
<tr ng-repeat="item in filteredItems = (items | filter:searchValue)">
...
</tr>
Controller:
控制器:
$scope.toggleAll = function () {
angular.forEach($scope.filteredItems, function (item) {
// do stuff
})
}
#2
1
Your issue is that ng-repeat is scope isolated. As a result you can't refer to the internal list that is being managed by ng-repeat from your controller/directive.
您的问题是,ng-repeat是隔离的范围。因此,您无法从控制器/指令中引用由ng-repeat管理的内部列表。
As a result there are 2 options
因此有两个选择
-
Bind the filtered list to ng-repeat from your controller/directive, so you maintain the filtered list.
将过滤后的列表从控制器/指令绑定到ng-repeat,这样就可以维护过滤后的列表。
//in your controller $scope.filteredItems = $filter('yourFilter')($scope.items,$scope.searchText); $scope.$watch('searchText', function(newValue){ $scope.filteredItems = $filter('yourFilter')($scope.items, newValue); }); //in your view <tr ng-repeat="item in filteredItems"> <td>{{item.id}}</td> <td>{{item.name}}</td> </tr>
-
Perform the filter again in your controller/directive
在控制器/指令中再次执行过滤器
$scope.toggleAll() { var items = $filter('yourFilter')($scope.items, $scope.searchText); for(var i in items){ //set your selected property } }
#3
1
Angular filters create a new array. So in order to perform an action on the filtered items you're going to have to capture the new array.
角过滤器创建一个新的阵列。为了对过滤后的项执行操作,你需要捕获新的数组。
Something like:
喜欢的东西:
$scope.toggleAll() {
var filteredItems = $filter('filter')($scope.items, $scope.searchValue);
for(var i in filteredItems) {
...
}
}
If you don't want to filter twice you'll have to filter the array yourself every time searchValue
changes and ng-repeat
over that filtered array, ng-change is useful in that case.
如果你不想要过滤两次,你必须自己过滤数组,每次searchValue的改变和ng-repeat的过滤,在这种情况下,ng-change是有用的。