Angularjs 如何从控制器中推送到通过ng repeat进行迭代的数组?

Angularjs 如何从控制器中推送到通过ng repeat进行迭代的数组?,angularjs,controller,ng-repeat,Angularjs,Controller,Ng Repeat,这是我不知道的Angular的行为 假设我在控制器中有一个项目数组,我将在视图中重复这些项目。我在视图中有一个按钮,当我点击它时,一个项目被推入数组。在视图中更新ng重复列表。到目前为止一切都很好 但是。 如果我只是在控制器内的数组中推送一个新项目(比如,我设置了一个超时),视图中的ng repeat将不会注册数组的更改 关于plunker的示例: HTML: 观察到的行为:单击按钮将触发addName功能,并将一项添加到列表中setTimeout将在数组中推送一个项目,但这不会反映在视图中。在

这是我不知道的Angular的行为

假设我在控制器中有一个项目数组,我将在视图中重复这些项目。我在视图中有一个按钮,当我点击它时,一个项目被推入数组。在视图中更新ng重复列表。到目前为止一切都很好

但是。 如果我只是在控制器内的数组中推送一个新项目(比如,我设置了一个超时),视图中的ng repeat将不会注册数组的更改

关于plunker的示例:

HTML:

观察到的行为:单击按钮将触发
addName
功能,并将一项添加到列表中<但是,code>setTimeout将在数组中推送一个项目,但这不会反映在视图中。在检查控制台日志的结果时,我看到显示的项有一个
$$hashKey
属性,简单地推送到数组将导致缺少此属性的项


问题:向控制器中的数组添加项目的正确方法是什么?我应该使用$digest还是$apply或其他什么吗?

Angular的工作原理是,如果观察到的模型值发生了更改,则定期执行脏检查。它在所谓的
$digest
周期中实现这一点。当Angular认为有必要时,这些循环会自动运行,但如果事件发生在Angular上下文之外,Angular将不知道该事件,不会触发
$digest
循环,不会检测到更改,并且不会更新视图

将值推送到数组(角度上下文之外)时,需要手动运行$digest循环,例如,将函数包装到
$scope.evalAsync()
,这将触发范围内的脏检查

更新:是的,您也可以调用
$scope.$digest()
,但问题是,如果$digest循环已经在运行,您将得到不知名的“$digest()已在进行中”错误

$scope.evalAsync()
不会遇到该问题,因为它异步触发
$digest
循环。更重要的是,如果一个
$digest
周期已经在进行中,它将尝试在同一个周期中完成工作,并且不会不必要地触发一个新的周期


您还可以看到Ben Nadel的这篇文章,他对所有内容进行了更详细的解释(例如,与使用
$timeout
服务进行比较,这是另一种选择)。

Angular的工作原理是,如果观察到的任何模型值发生变化,则定期执行脏检查。它在所谓的
$digest
周期中实现这一点。当Angular认为有必要时,这些循环会自动运行,但如果事件发生在Angular上下文之外,Angular将不知道该事件,不会触发
$digest
循环,不会检测到更改,并且不会更新视图

将值推送到数组(角度上下文之外)时,需要手动运行$digest循环,例如,将函数包装到
$scope.evalAsync()
,这将触发范围内的脏检查

更新:是的,您也可以调用
$scope.$digest()
,但问题是,如果$digest循环已经在运行,您将得到不知名的“$digest()已在进行中”错误

$scope.evalAsync()
不会遇到该问题,因为它异步触发
$digest
循环。更重要的是,如果一个
$digest
周期已经在进行中,它将尝试在同一个周期中完成工作,并且不会不必要地触发一个新的周期


您还可以看到Ben Nadel的这篇文章,他对所有内容进行了更详细的解释(例如,与使用
$timeout
服务进行比较,这是另一种选择)。

Angular的工作原理是,如果观察到的任何模型值发生变化,则定期执行脏检查。它在所谓的
$digest
周期中实现这一点。当Angular认为有必要时,这些循环会自动运行,但如果事件发生在Angular上下文之外,Angular将不知道该事件,不会触发
$digest
循环,不会检测到更改,并且不会更新视图

将值推送到数组(角度上下文之外)时,需要手动运行$digest循环,例如,将函数包装到
$scope.evalAsync()
,这将触发范围内的脏检查

更新:是的,您也可以调用
$scope.$digest()
,但问题是,如果$digest循环已经在运行,您将得到不知名的“$digest()已在进行中”错误

$scope.evalAsync()
不会遇到该问题,因为它异步触发
$digest
循环。更重要的是,如果一个
$digest
周期已经在进行中,它将尝试在同一个周期中完成工作,并且不会不必要地触发一个新的周期


您还可以看到Ben Nadel的这篇文章,他对所有内容进行了更详细的解释(例如,与使用
$timeout
服务进行比较,这是另一种选择)。

Angular的工作原理是,如果观察到的任何模型值发生变化,则定期执行脏检查。它在所谓的
$digest
周期中实现这一点。当Angular认为有必要时,这些循环会自动运行,但如果事件发生在Angular上下文之外,Angular将不知道该事件,不会触发
$digest
循环,不会检测到更改,并且不会更新视图

将值推送到数组(角度上下文之外)时,需要手动运行$digest循环,例如,将函数包装到
$scope.evalAsync()
,这将触发范围内的脏检查

更新:是的,您可以
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="http://apps.bdimg.com/libs/angular.js/1.4.0-beta.4/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="myApp">
    <main ng-controller="MainController as ctrl">
      <button ng-click="ctrl.addName()">Add an item</button>
      <ul>
        <li ng-repeat="name in ctrl.names">
          {{name.name}}
        </li>
      </ul>
    </main>
  </body>

</html>
angular.module('myApp', [])
  .controller('MainController', function(){
    var self = this;

    self.test = 2;
    self.names = [{name: 'example'}];

    self.addName = function(){
      self.names.push({name: 'new example'});
      console.log(self.names)
    };

    setTimeout(function(){
      self.names.push({name: 'another example'});
      console.log(self.names);
    }, 1000);

  });