Angularjs:为什么$watch中的$scope.variable不是最新的?

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

我创建了一个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: <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>