【发布时间】:2015-10-01 14:42:27
【问题描述】:
这是我不知道的 Angular 行为。
假设我在控制器中有一个项目数组,我在视图中重复它们。我在视图中有一个按钮,当我单击它时,会在数组中推送一个项目。 ng-repeated 列表在视图中得到更新。到目前为止一切都很好。
但是。 如果我只是在控制器内部的数组中推送一个新项目(假设我设置了一个超时时间),视图中的 ng-repeat 不会注册数组的更改。
plunker 示例:http://plnkr.co/edit/1mlOpGVOXmnCAa8W5KEx?p=preview
HTML:
<!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>
JS:
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);
});
观察到的行为:单击按钮将触发addName 函数并将一个项目添加到列表中。 setTimeout 但是会在数组中推送一个项目,但这不会反映在视图中。在检查控制台日志的结果时,我看到显示的项目具有$$hashKey 属性,简单地推送到数组将导致缺少该属性的项目。
问题:向控制器中的数组添加项目的正确方法是什么?我应该使用 $digest 还是 $apply 之类的?
【问题讨论】:
-
setTimeout是作为从控制器内调用的函数的示例给出的。我的实际代码响应控制器中触发的事件并将项目推送到数组。 -
该函数将如何触发?如果你手动调用,你仍然需要包裹在 $timeout 或 $applyAsync 或 $evalAsync 或 $$postDigest 之类的东西中。如果你从 $http.get 调用它,它会自动触发。
-
我正在使用第三方地理映射库。它返回一个承诺,当这个承诺得到解决时,我正在控制器中调用一个函数。然后,该函数会将返回的任何承诺添加到控制器上的
this.names数组中。但是显然,角度上下文丢失了。所以我想知道如何恢复它。 -
是的,这不是 Angular 的承诺,因此,您需要使用我提到的上述方法之一手动触发它。 (例如,
$scope.$applyAsync(function(){self.names.push({name: 'another example'});});)
标签: angularjs controller ng-repeat