与AngularJS执行控制器相冲突两次

我知道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条logging。 我显然还在学习,因为我一直对这个头撞过头!

应用程序路由器指定导航到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"> 

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

AngularJS文档 – ngController
请注意,您也可以通过$ route服务在路由定义中声明它来将控制器附加到DOM。 一个常见的错误是在模板中使用ng-controller再次声明控制器。 这将导致控制器被连接和执行两次。

当你将ngRoute和ng-view指令一起使用时,默认情况下,控制器会连接到那个dom元素(或者如果你使用ui-router的话,则是ui-view)。 所以你不需要在模板中重新附加它。

我刚刚经历了这个,但是这个问题与被接受的答案不同。 我真的要把这个留给我未来的自我,包括我经历的一些步骤来解决这个问题。

  1. 删除多余的控制器声明
  2. 检查路线中的尾部斜杠
  3. 检查ng-ifs
  4. 检查任何不必要的包装ng-view调用(我不小心留在一个ng-view ,包装我的实际ng-view ,这导致了三个调用我的控制器。
  5. 如果你在Rails上,你应该从你的application.js文件中删除turbolinks gem。 我浪费了一整天的时间来发现这一点。 在这里find答案。
  6. 用ng-app和bootstrap初始化应用程序两次。 与AngularJS执行控制器相冲突两次
  7. 在使用$ link编译整个元素的指令的'link' – 也有自己定义的控制器的函数时,通过ng-click在模板中使用这个控制器的callback。在这里find答案。

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

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

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

要解决它只是改变ng – 如果ng-show / ng-hide和所有将工作正常。

想补充参考:

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

例如

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

当你在你的HTML中也有ng-controller =“myController”时

在Angular 1.3+中使用angular-ui-router时, 在路由转换时出现两次渲染视图的问题。 这导致执行两次控制器。 没有任何提议的解决scheme为我工作。

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

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

 <html ng-app="mTest1"> 

我也手动引导它使用angular.bootstrap ie

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

所以删除其中的一个,它为我工作。

我撕毁我的应用程序和所有的依赖关于这个问题(详细在这里: AngularJS应用程序启动两次(尝试通常的解决scheme..) )

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

解决方法:

我强烈build议任何人的名单上的第一件事是在更改代码之前禁用它。

如果您知道您的控制器不小心执行了多次,请尝试通过文件search违规控制器的名称,例如:search:MyController,通过所有文件。 有可能在其他html / js文件中被复制粘贴,并且当你开发或使用这些部分/控制器时,你忘记了改变它。 来源:我犯了这个错误

在某些情况下,当你不正确地closures你的指令时,你的指令会运行两次:

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

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

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

一直在用AngularJS 1.4 rc构build这个问题,然后意识到上面的答案都不适用,因为它是在本文写作的时候从Angular 1.4和Angular 2的新路由器库中发展而来的。 因此,对于任何可能使用新的Angular路线库的人来说,我都会在这里留下一个提示。

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

还没有find一个可行的解决方法,但我相信这个行为是符合shaunxu提出的观察,并希望这个问题将在未来build立新的路线库,并与AngularJS 1.4版本一起解决。

在我的情况下,我发现使用相同的控制器的两个意见。

 $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' } } }); 

我遇到的问题可能是切题的,但是由于谷歌search引起我这个问题,这可能是适当的。 这个问题在使用UI路由器时会给我带来难看的东西,但是只有当我尝试用浏览器刷新button来刷新页面的时候。 该应用程序使用父级抽象状态的UI路由器,然后子级closures父级。 在应用程序的run()函数中,有一个$state.go('...child-state...')命令。 父母状态使用一个resolve ,起初我想也许一个孩子控制器执行两次。

在URL添加哈希之前,一切正常。
www.someoldwebaddress.org

然后,一旦URL路由器已经修改了URL,
www.someoldwebaddress.org#/childstate

…然后当我用浏览器刷新button刷新页面时$stateChangeStart触发两次,每次指向childstate

父母状态的resolve是两次发射。

也许这是一个混蛋; 无论如何,这似乎消除了我的问题:在$stateProvider第一次被调用的代码区域, 首先检查是否window.location.hash是一个空string。 如果是的话,一切都好。 如果不是,则将window.location.hash设置为空string。 那么$state似乎只是试图去某个地方,而不是两次。

此外,如果您不想依赖应用程序的默认runstate.go(...) ,则可以尝试捕获散列值,并使用散列值确定页面刷新之前的子状态,并在你设置state.go(...)代码中添加一个条件。

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

我的url是/ ui / project /:parameter1 /:parameter2。

在所有状态变化的情况下,我都不需要参数2。 在我不需要第二个参数的情况下,我的url就像/ ui / project /:parameter1 /。 所以每当我有一个状态改变,我会让我的控制器刷新两次。

解决的办法是将parameter2设置为空string并进行状态更改。

我有这个双重初始化发生了一个不同的原因。 对于我的应用程序中的一些path转换,我想强制滚动到页面的顶部附近(例如,在分页的search结果中…单击下一步应带您到页面2的顶部)。

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

 $location.hash('top'); 

不经意间,这导致我的路线被重新评估,pipe制员被重新初始化

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

你可以在这里阅读更多关于它

控制器由于在URL中追加params而被调用两次

我有同样的问题,并尝试所有的答案后,我终于发现,我有一个指令,在我看来是绑定到相同的控制器。

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

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

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

我的解决很简单。 我刚从$state.go("app.reader", { fileName: fn, reload: true });移除了reload:true $state.go("app.reader", { fileName: fn, reload: true }); 在我的LibraryController

我想我的两次被调用是因为我从我的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()被调用两次。 希望它可以帮助别人。