【问题标题】:Why is ng-change one step behind in the console?为什么 ng-change 在控制台中落后一步?
【发布时间】:2016-01-22 15:17:45
【问题描述】:

Plunker:http://plnkr.co/edit/u3olPFyiT7tFdKKVvzZf?p=preview

我有一个列表和一个过滤所述列表的输入。

如果您在键入时查看屏幕上的“结果”数字,那是正确的。但是如果你看控制台中的数字,它似乎总是落后一步。

为什么?又该如何解决?

JS:

  $scope.users = [
    'mike',
    'john',
    'pete'
  ]

  $scope.results = [];

  $scope.count_results = function() {
    console.log($scope.results.length)
  }

HTML:

<input type="text" class="form-control" ng-model="user_name" ng-change="count_results()">
<ul class="dropdown-menu">
    <li ng-repeat="user in results = (users | filter: user_name) | limitTo: 3">{{user}}</li>
</ul>
Results: {{results.length}}

【问题讨论】:

  • "why" 部分相当简单......你想做什么?

标签: javascript angularjs filter angularjs-ng-repeat ng-repeat


【解决方案1】:

您可以使用$watch 处理它。我将代码编辑如下:

http://plnkr.co/edit/R3QRa1bhGyNwAeU6OOVb?p=preview

【讨论】:

  • 手表制作方法存在严重缺陷。将为输入的每个字母添加一个新手表。是复合手表。不要在事件处理程序中创建它。还应该在答案中发布代码并仅使用演示作为概念证明
  • @charlietfl - 你的解决方案是什么?
  • 可以使用手表...但不要在每次 UI 事件触发时创建新的。慢慢输入p..e..t..e时看看控制台
【解决方案2】:

原因是ng-change在过滤器过滤列表之前执行。在执行ng-change 的那一刻,result 未设置为新列表,因此控制台输出显示的是过滤前旧列表的长度。

编辑:

当您在ng-change mehtod 内而不是在视图中执行过滤时,您可以解决此问题。然后只显示结果。见我的plunker

  $scope.count_results = function() {
      $scope.results = $filter('filter')($scope.users, $scope.user_name);
      console.log($scope.results.length)
  }

【讨论】:

  • 那么如何让控制台显示正确的result号码?
【解决方案3】:

ng-modelng-change 都将 change 事件侦听器添加到应用它们的输入。当您输入输入时,将执行事件处理程序(其中包括您的count_results)。事件侦听器导致模块值更改并触发新的$digest 循环。

$digest 循环是 Angular 将旧模型值与新模型值进行比较并相应更新视图的地方。届时将使用更新的条件应用过滤器以缩小列表范围。

您添加即

<span class="{{count_results()}}"></span>

您会看到console.log 被多次打印,最后一个值始终保持同步。然而,这毫无用处,我怀疑你更愿意在你的控制器中拥有$watch

$scope.$watch('results.length', function(newValue, oldValue){
   console.log('new value is', newValue);
});

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2016-07-26
    • 2017-08-25
    • 2014-09-01
    • 1970-01-01
    • 2016-09-23
    • 2017-02-08
    • 2019-10-30
    • 2015-07-24
    相关资源
    最近更新 更多