我需要为a
标签生成http链接。出于这个原因,我输入了html
行
<a href="{{getLink(url)}}">My link</a>
在控制器中,它定义为:
$scope.getLink = function(inputUrl){
$http.get(inputUrl).success(function(data){/*.....*/});
}
为什么 AngularJS 最终会陷入无限循环?什么是正确的设计?
如另一个答案中所述,在每个摘要上评估监视的表达式,并将结果值与其以前的值进行比较 - 脏检查。如果存在更改,则会启动摘要的另一个迭代,因为一个值的更改可能会导致另一个值的更改。
如果存在循环依赖关系(包括 1 的圆,即相同的表达式每次都不同),则会导致 Angular 在 10 次迭代后停止的无限循环。
具体来说,getLink
函数的返回值是一个承诺($http 的返回值),并且 Angular 绑定不会"等待"一个承诺。
您要做的是启动$http
调用,并在其处理程序中将返回值分配给将绑定到<a>
的 ViewModel 属性:
function getLink(){
$http.get(inputUrl)
.success(function(data){
$scope.url = data.data;
});
}
您可以调用getLink
,例如,当控制器运行时。
在视图中,您只需将url
绑定到ng-href
(而不是href
)属性:
<a ng-href="url">My Link</a>
一旦您在视图中添加 Angular 表达式,例如 {{expression}}
,它将被添加到当前范围的监视列表中。
Angular 使用一种称为 dirty checking
的机制来存档双向绑定。每次发生一些特定事件时,Angular 都会浏览监视列表以检查监视值是否已更改,此操作称为 digest loop
。
这里some specific events
包括用户输入、模型更改、$http请求完成等。当您在表达式中使用getLink
函数时,每次当 Angular 触发脏检查/摘要循环时,都会再次执行此函数以检查其返回结果是否已更改。
问题是,这里getLink
的函数是一个$http请求,执行后,Angular 会触发另一轮脏检查,它会再次执行这个函数......砰,这是一个无限循环。
结论:不要在角度表达式中添加任何$http调用。