我知道AngularJS会将一些代码运行两次,有时甚至更多,比如$watch events,不断检查模型状态等等。

然而我的代码:

function MyController($scope, User, local) {

var $scope.User = local.get(); // Get locally save user data

User.get({ id: $scope.User._id.$oid }, function(user) {
  $scope.User = new User(user);
  local.save($scope.User);
});

//...

执行两次,将2条记录插入到我的DB中。我显然还在学习,因为我已经用我的头撞它很多年了!


当前回答

只是想再添加一个控制器可以init两次的情况(这是实际的angular.js 1.3.1):

<div ng-if="loading">Loading...</div>
<div ng-if="!loading">
    <div ng-view></div>
</div>

在本例中为$route。ng-view初始化时,Current已经设置。会导致双重初始化。

要修复它,只需将ng-if更改为ng-show/ng-hide,一切都将正常工作。

其他回答

我一直在用AngularJS 1.4 rc构建这个问题,然后意识到上面的答案都不适用,因为在撰写本文时,它起源于Angular 1.4和Angular 2的新路由器库。因此,我要在这里提醒那些可能正在使用新的Angular路由库的人。

基本上,如果一个html页面包含一个ng-viewport指令来加载你的应用程序的部分,通过点击ng-link中指定的超链接将导致相关组件的目标控制器被加载两次。细微的区别在于,如果浏览器已经加载了目标控制器,那么重新单击相同的超链接只会调用该控制器一次。

还没有找到可行的解决方案,尽管我相信这个行为与shaunxu提出的观察是一致的,希望这个问题能在未来的新路由库构建中以及AngularJS 1.4版本中得到解决。

在这里加上我的案例:

我使用angular-ui-router和$state。Go ('new_state', {foo: "foo@bar"})

一旦我将encodeURIComponent添加到参数中,问题就解决了:$state。go('new_state', {foo: encodeURIComponent("foo@bar")})。

发生了什么事? 参数值中的“@”字符不允许出现在url中。因此,angular-ui-router创建了我的控制器两次:在第一次创建时,它传递了原始的“foo@bar”,在第二次创建时,它将传递编码版本“foo%40bar”。一旦我像上面那样显式地对参数进行编码,问题就解决了。

由于不同的原因,我已经有了这个双重初始化。对于我的应用程序中的一些路由转换,我想强制滚动到接近页面顶部(例如在分页搜索结果中……)单击next会将您带到第2页的顶部)。

我通过在$viewContentLoaded上的$rootScope $中添加一个侦听器来实现这一点(基于某些条件)

$location.hash('top');

无意中,这导致我的路由被重新评估,控制器被重新初始化

在我的例子中,重命名控制器为不同的名称解决了问题。

控制器名称与“angular-ui-tree”模块有冲突:我将我的控制器从“CatalogerTreeController”重命名为“TreeController”,然后这个控制器开始在“ui-tree”指令使用的页面上初始化两次,因为这个指令使用名为“TreeController”的控制器。

特此补充,以供参考:

在同样运行在页面上的指令中引用控制器也可能导致双控制器代码执行。

e.g.

return {

            restrict: 'A',
            controller: 'myController',
            link: function ($scope) { ....

当你也有ng-controller="myController"在你的HTML