Angularjs:为什么$watch中的$scope.variable不是最新的?
我创建了一个Plunker来说明这个问题。以下是主要代码:Angularjs:为什么$watch中的$scope.variable不是最新的?,angularjs,directive,Angularjs,Directive,我创建了一个Plunker来说明这个问题。以下是主要代码: <body ng-controller="MainCtrl"> <table class="table table-bordered table-striped table-condensed table-hover"> <caption class="text-left" style="background-color: lightgray"> Search: &
<body ng-controller="MainCtrl">
<table class="table table-bordered table-striped table-condensed table-hover">
<caption class="text-left" style="background-color: lightgray">
Search: <input ng-model="searchString" style="width: 80px" />
Filted count: {{filteredList.length}}
</caption>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Sex</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="emp in filteredList = (data.employees | filter:searchString)">
<td>{{emp.firstName}}</td>
<td>{{emp.lastName}}</td>
<td>{{emp.sex}}</td>
</tr>
</tbody>
</table>
</body>
问题是filteredList.length的console.log总是落后一个循环(与正确的html相比),也就是说,落后于前一个过滤器。如何修复它?只要
searchString
发生更改,您就可以记录filteredList.length
。但是,目前,filteredList
中的过滤器尚未修改ngRepeat
解决此问题的一种方法是使用$watch
filteredList.length
:
$scope.$watch(function() {
return ($scope.filteredList || []).length;
...
更新我真的很喜欢shaunhusain的评论。他的建议可能更接近你真正想做的
$scope.searchString = '';
// Initialize filteredItems as a copy of data.employees
$scope.filteredItems = angular.copy($scope.data.employees);
// Watch your search string instead and apply filtering using $filter
$scope.$watch(function() {
return $scope.searchString;
},
function(str) {
$scope.filteredItems = $filter('filter')($scope.data.employees, {$: $scope.searchString}, false);
console.log($scope.filteredItems.length);
});
然后,您的ngRepeat
就是:
<tr ng-repeat="emp in filteredItems">
<td>{{emp.firstName}}</td>
<td>{{emp.lastName}}</td>
<td>{{emp.sex}}</td>
</tr>
{{emp.firstName}
{{emp.lastName}
{{emp.sex}
如果searchString发生变化,它将触发您的watch表达式,因为它还将导致调用$apply/$digest来更新绑定的任何DOM元素。当它更新DOM元素时,它将重新运行表达式并更新filterdList变量(但此时它已经触发了监视,为时已晚)。我会考虑从一个控制器函数(也许在这个表中)应用赋值和过滤函数,这样你就可以同步地做事情。
<tr ng-repeat="emp in filteredItems">
<td>{{emp.firstName}}</td>
<td>{{emp.lastName}}</td>
<td>{{emp.sex}}</td>
</tr>