提问



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


不过我的代码:


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条记录插入我的数据库。我显然还在学习,因为我多年来一直在反对这个!

最佳参考


应用程序路由器指定导航到MyController,如下所示:


$routeProvider.when('/',
                   { templateUrl: 'pages/home.html',
                     controller: MyController });


但我home.html也有这个:


<div data-ng-controller="MyController">


这消化了控制器两次。从HTML中删除data-ng-controller属性解决了问题。或者,controller:属性可能已从路由指令中删除。


使用选项卡式导航时也会出现此问题。例如,app.js可能包含:


  .state('tab.reports', {
    url: '/reports',
    views: {
      'tab-reports': {
        templateUrl: 'templates/tab-reports.html',
        controller: 'ReportsCtrl'
      }
    }
  })


相应的报告选项卡HTML可能类似于:


<ion-view view-title="Reports">
  <ion-content ng-controller="ReportsCtrl">


这也将导致控制器运行两次。

其它参考1



  AngularJS docs - ngController

  请注意,您还可以通过声明将控制器附加到DOM
  在路由定义中通过$ route服务。 常见的错误是
  在模板中使用ng-controller再次声明控制器
  本身。这将导致控制器被附加和执行
  两次。
[55]



将ngRoute与ng-view指令一起使用时,控制器默认附加到该dom元素(如果使用ui-router,则为ui-view)。因此,您无需再次在模板中附加它。

其它参考2


我刚刚完成了这个,但问题与接受的答案不同。我真的把这个留给了我未来的自我,包括我修复它的步骤。



  1. 删除冗余控制器声明

  2. 检查路线中的尾部斜杠

  3. 检查ng-ifs

  4. 检查是否有任何不必要的包裹ng-view调用(我不小心在ng-view中留下了包裹我的实际ng-view。这导致三次调用我的控制器。)

  5. 如果您使用的是Rails,则应从application.js文件中删除turbolinks gem。我浪费了一整天才发现这一点。在这里找到答案。

  6. 使用ng-app和bootstrap初始化应用程序两次。两次打击AngularJS执行控制器

  7. 在link函数中对整个元素使用$ compile时,也有自己的控制器定义的指令函数,并通过ng-click等在模板中使用该控制器的回调。在这里找到答案。


其它参考3


只想在控制器初始化两次时添加一个案例(这对于angular.js 1.3.1来说是实际的): [59]


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


在这种情况下,当ng-view将初始化时,将设置$ route.current。这导致双重初始化。


要修复它,只需更改ng-if到ng-show/ng-hide,一切都会正常。

其它参考4


想补充参考:


双控制器代码执行也可以通过在也在页面上运行的指令中引用控制器来引起。


例如


return {

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


你的HTML中还有ng-controller =myController

其它参考5


当使用具有Angular 1.3+的angular-ui-router时,在路由转换时出现两次渲染视图的问题。这导致执行控制器两次。所提议的解决方案都不适合我。[62] [63]


但是,将angular-ui-router从0.2.11更新为0.2.13解决了我的问题。

其它参考6


我把我的应用程序及其所有依赖项撕成了这个问题(详情请参阅:AngularJS应用程序启动两次(尝试通常的解决方案..))


最后,这是所有Batarang Chrome插件的错。


这个答案中的决议:





我强烈建议任何人的第一件事就是在改变代码之前根据帖子禁用它。

其它参考7


我有一个相同的问题,在一个简单的应用程序(没有路由和简单的ng控制器参考)和我的控制器的构造函数确实运行了两次。最后,我发现我的问题是以下声明自动引导我的AngularJS我的Razor视图中的应用程序


<html ng-app="mTest1">


我也用angular.bootstrap手动引导它,即


angular.bootstrap(document, [this.app.name]);


所以删除其中一个,它对我有用。

其它参考8


如果您知道您的控制器无意中执行了多次,请尝试在您的文件中搜索有问题的控制器的名称,例如:搜索:MyController到所有文件。可能它在其他一些html/js文件中被复制粘贴,当你开发或使用那些部分/控制器时你忘了改变它。来源:我犯了这个错误

其它参考9


在某些情况下,如果您没有正确关闭指令,那么您的指令会运行两次:


<my-directive>Some content<my-directive>


这将运行您的指令两次。
当你的指令运行两次时,还有另一种情况:


确保您没有在index.html TWICE 中包含您的指令!

其它参考10


在AngularJS 1.4 rc版本中,我一直在解决这个问题,然后意识到上述答案都不适用,因为它是在撰写本文时源自Angular 1.4和Angular 2的新路由器库。因此,我正在为可能正在使用新Angular路径库的任何人留下一个注释。[66]


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


Haven尚未找到可行的解决方法,但我相信这种行为与shaunxu提出的观点一致,并且希望这个问题能够在未来构建新路由库以及AngularJS 1.4版本时得到解决。[67]

其它参考11


就我而言,我发现两个视图使用相同的控制器。


$stateProvider.state('app', {
  url: '',
  views: {
    "viewOne@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/one.tpl.html'
    },
    "viewTwo@app": {
      controller: 'CtrlOne as CtrlOne',
      templateUrl: 'main/two.tpl.html'
    }
  }
});

其它参考12


我遇到的问题可能是切线,但由于谷歌搜索引发了我这个问题,这可能是合适的。在使用UI路由器时,这个问题对我来说很难看,但只有当我尝试使用浏览器刷新按钮刷新页面时才会出现问题。该应用程序使用具有父抽象状态的UI路由器,然后子项关闭父项。在app run()函数中,有一个$state.go('...child-state...')命令。父状态使用resolve,起初我认为子控制器可能正在执行两次。


在URL附加了哈希之前,一切都很好
www.someoldwebaddress.org


然后,一旦url被UI路由器修改,

www.someoldwebaddress.org#/childstate


...然后当我使用浏览器刷新按钮刷新页面时,$stateChangeStart会触发两次,每次都指向childstate


父状态的resolve是两次射击。


也许这是一个kludge;无论如何,这似乎消除了我的问题:在首次调用$stateProvider的代码区域中,首先检查 window.location.hash 是一个空字符串。如果是的话,一切都很好;如果不是,则将 window.location.hash 设置为空字符串。然后似乎$state只试图去某个地方而不是两次。


此外,如果您不想依赖应用程序的默认runstate.go(...),您可以尝试捕获哈希值并使用哈希值来确定您之前所处的子状态页面刷新,并在代码中为您设置state.go(...)的区域添加条件。

其它参考13


在我的情况下,这是因为我使用的网址模式


我的网址就像/ui/project/:parameter1/:parameter2。


在所有状态变化的情况下我都不需要参数2。如果我不需要第二个参数,我的url就像/ui/project/:parameter1/。因此,每当我进行状态更改时,我的控制器都会刷新两次。


解决方案是将parameter2设置为空字符串并执行状态更改。

其它参考14


我已经将这种双重初始化发生在另一个原因。对于我的应用程序中的一些路径转换,我想强制滚动到页面顶部附近(例如,在分页搜索结果中...单击下一步应该会带您到顶部第2页)。


我通过在$rootScope $on $viewContentLoaded中添加一个监听器来执行此操作,该监听器(基于某些条件)执行


$location.hash('top');


不经意间,这导致我的路线被重新评估并且控制器被重新初始化

其它参考15


我的问题是如此更新搜索参数$location.search('param', key);


你可以在这里读更多关于它的内容


控制器因为在url中附加params而被调用两次

其它参考16


在我的情况下,将控制器重命名为另一个名称解决了问题。


控制器名称的冲突与 angular-ui-tree 模块:我将控制器从CatalogerTreeController重命名为 TreeController 然后在使用 ui-tree 指令的页面上启动此控制器两次,因为该指令使用名为 TreeController 的控制器。

其它参考17


我有同样的问题,在尝试了所有的答案后,我终于发现我的视图中有一个指令绑定到同一个控制器。


APP.directive('MyDirective', function() {
  return {
    restrict: 'AE',
    scope: {},
    templateUrl: '../views/quiz.html',
    controller: 'ShowClassController'
}
});


删除指令后,控制器停止被调用两次。现在我的问题是,如何使用此指令绑定到控制器范围而没有这个问题?

其它参考18


我刚解决了我的问题,实际上非常令人失望。它是一个离子混合应用程序,我使用过ui-router v0.2.13。在我的情况下有一个epub阅读器(使用epub.js),一旦我导航到我的书库并选择任何一个,它不断报告没有找到文件当我重新加载浏览器时,书籍被完美呈现,但是当我选择另一本书时又遇到了同样的问题。


我的解决很简单。我刚从LibraryController LibraryController中删除reload:true

其它参考19


我在angular-route@1.6.7中遇到了同样的问题,因为正则表达式路径末尾的额外斜杠:


.when('/goods/publish/:classId/', option)





.when('/goods/publish/:classId', option)


它工作正常。

其它参考20


我发现我的两次调用是因为我从我的html中调用了两次方法。


`<form class="form-horizontal" name="x" ng-submit="findX() novalidate >
 <input type="text"....>
 <input type="text"....>
 <input type="text"....>
 <button type="submit" class="btn btn-sm btn-primary" ng-click="findX()"
</form>`


突出显示的部分导致findX()被调用两次。希望它可以帮到某人。