我了解 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 条记录插入我的数据库。我显然仍在学习,因为我多年来一直在努力解决这个问题!
ng-app
和手动引导程序自动初始化它)。还要检查您是否已将控制器附加到多个元素(使用 ng-controller)。
应用路由器指定导航到 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 docs - ngController 请注意,您还可以通过 $route 服务在路由定义中声明控制器来将控制器附加到 DOM。一个常见的错误是在模板本身中使用 ng-controller 再次声明控制器。这将导致控制器被附加并执行两次。
当您使用带有 ng-view
指令的 ngRoute 时,控制器默认附加到该 dom 元素(如果您使用 ui-router,则附加到 ui-view)。因此,您无需在模板中再次附加它。
我刚刚经历了这个,但问题与接受的答案不同。我真的要把它留在这里,为了我未来的自己,包括我修复它所经历的步骤。
删除多余的控制器声明 检查路由中的尾部斜杠 检查 ng-ifs 检查任何不必要的包装 ng-view 调用(我不小心留在了包装我的实际 ng-view 的 ng-view 中。这导致对我的控制器的三个调用.) 如果你在 Rails 上,你应该从你的 application.js 文件中删除 turbolinks gem。我浪费了一整天的时间来发现这一点。在这里找到答案。使用 ng-app 和 bootstrap 初始化应用程序两次。对抗 AngularJS 执行控制器两次当在指令的“链接”函数中对整个元素使用 $compile 时,该指令还定义了自己的控制器,并通过 ng-click 等在模板中使用该控制器的回调。在这里找到答案。
只想在控制器可以初始化两次时再添加一种情况(这对于 angular.js 1.3.1 来说是实际的):
<div ng-if="loading">Loading...</div>
<div ng-if="!loading">
<div ng-view></div>
</div>
在这种情况下,$route.current 将在 ng-view 初始化时设置。这会导致双重初始化。
要修复它,只需将 ng-if 更改为 ng-show/ng-hide,一切都会正常工作。
ui-view
两次调用控制器。
想补充以供参考:
在页面上运行的指令中引用控制器也可能导致双重控制器代码执行。
例如
return {
restrict: 'A',
controller: 'myController',
link: function ($scope) { ....
当您的 HTML 中也有 ng-controller="myController" 时
将 angular-ui-router 与 Angular 1.3+ 一起使用时,存在关于 Rendering views twice on route transition 的问题。这也导致两次执行控制器。建议的解决方案都不适合我。
但是,将 angular-ui-router
从 0.2.11 更新到 0.2.13 为我解决了问题。
我在这个问题上撕毁了我的应用程序及其所有依赖项(详细信息:AngularJS app initiating twice (tried the usual solutions..))
最后,这都是 Batarang Chrome 插件的错。
this answer 中的分辨率:
https://i.stack.imgur.com/AWufV.png
我强烈建议任何人列表中的第一件事是在更改代码之前根据帖子禁用它。
如果您知道您的控制器无意中执行了多次,请尝试在您的文件中搜索有问题的控制器的名称,例如:搜索:MyController 通过所有文件。很可能它被复制粘贴到其他一些 html/js 文件中,而当您开发或使用这些部分/控制器时忘记更改它。来源:我犯了这个错误
我在一个简单的应用程序中遇到了同样的问题(没有路由和简单的 ng-controller 引用),并且我的控制器的构造函数确实运行了两次。最后,我发现我的问题是在我的 Razor 视图中自动引导我的 AngularJS 应用程序的以下声明
<html ng-app="mTest1">
我还使用 angular.bootstrap 手动引导它,即
angular.bootstrap(document, [this.app.name]);
所以删除其中一个,它对我有用。
在某些情况下,当您根本不正确关闭您的指令时,您的指令会运行两次,如下所示:
<my-directive>Some content<my-directive>
这将运行您的指令两次。当您的指令运行两次时,还有另一种常见情况:
确保您的 index.html
TWICE 中没有包含您的指令!
一直在用 AngularJS 1.4 rc build 解决这个问题,然后意识到上述答案都不适用,因为它在撰写本文时源自 new router library for Angular 1.4 and Angular 2。因此,我在这里为可能正在使用新的 Angular 路由库的任何人做一个说明。
基本上,如果 html 页面包含用于加载应用程序部分的 ng-viewport
指令,则单击 ng-link
中指定的超链接会导致相关组件的目标控制器被加载两次。细微的差别在于,如果浏览器已经加载了目标控制器,通过重新点击同一个超链接只会调用一次控制器。
尚未找到可行的解决方法,但我相信此行为与 shaunxu 提出的观察结果一致,希望此问题将在新路由库的未来构建以及 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'
}
}
});
我遇到的问题可能是切题的,但由于谷歌搜索让我想到了这个问题,这可能是合适的。使用 UI Router 时,问题对我来说很丑陋,但只有当我尝试使用浏览器刷新按钮刷新页面时。该应用程序使用带有父抽象状态的 UI 路由器,然后是父抽象状态的子状态。在应用程序 run()
函数上,有一个 $state.go('...child-state...')
命令。父状态使用 resolve
,起初我认为可能是子控制器执行了两次。
在 URL 附加哈希之前一切正常。
www.someoldwebaddress.org
然后,一旦 UI 路由器修改了 URL,
www.someoldwebaddress.org#/childstate
...然后当我使用浏览器刷新按钮刷新页面时,$stateChangeStart
会触发两次,每次都指向 childstate
。
父状态上的 resolve
是触发两次的原因。
也许这是一个杂牌;无论如何,这似乎确实消除了我的问题:在第一次调用 $stateProvider
的代码区域中,首先检查 window.location.hash是一个空字符串。如果是,一切都很好;如果不是,则将 window.location.hash 设置为空字符串。然后看起来 $state
只尝试去某个地方一次而不是两次。
此外,如果您不想依赖应用程序的默认 run
和 state.go(...)
,您可以尝试捕获哈希值并使用哈希值来确定您在页面刷新之前所处的子状态,并添加条件到您设置 state.go(...)
的代码中的区域。
对于那些使用 ControllerAs 语法的人,只需在 $routeprovider 中声明控制器标签,如下所示:
$routeprovider
.when('/link', {
templateUrl: 'templateUrl',
controller: 'UploadsController as ctrl'
})
或者
$routeprovider
.when('/link', {
templateUrl: 'templateUrl',
controller: 'UploadsController'
controllerAs: 'ctrl'
})
声明 $routeprovider 后,不要像在视图中那样提供控制器。而是使用视图中的标签。
就我而言,这是因为我使用的 url 模式
我的网址就像 /ui/project/:parameter1/:parameter2。
在所有状态变化的情况下,我都不需要 paramerter2。在我不需要第二个参数的情况下,我的 url 将类似于 /ui/project/:parameter1/。所以每当我有状态改变时,我都会让我的控制器刷新两次。
解决方案是将 parameter2 设置为空字符串并进行状态更改。
由于不同的原因,我发生了这种双重初始化。对于我的应用程序中的一些路由转换,我想强制滚动到页面顶部附近(例如,在分页搜索结果中......单击下一步应该将您带到第 2 页的顶部)。
我通过向 $rootScope
$on
$viewContentLoaded
添加一个侦听器来做到这一点,该侦听器(基于某些条件)执行
$location.hash('top');
无意中,这导致我的路线被重新评估并且控制器被重新初始化
我的问题是像这样更新搜索参数 $location.search('param', key);
你可以在这里读更多关于它的内容
controller getting called twice due to append params in url
在我的情况下,将控制器重命名为不同的名称解决了这个问题。
控制器名称与“angular-ui-tree”模块存在冲突:我将控制器从“CatalogerTreeController”重命名为“TreeController”,然后该控制器开始在使用“ui-tree”指令的页面上启动两次,因为该指令使用名为“TreeController”的控制器。
我遇到了同样的问题,在尝试了所有答案后,我终于发现我的视图中有一个绑定到同一个控制器的指令。
APP.directive('MyDirective', function() {
return {
restrict: 'AE',
scope: {},
templateUrl: '../views/quiz.html',
controller: 'ShowClassController'
}
});
删除指令后,控制器停止被调用两次。现在我的问题是,如何使用绑定到控制器范围的这个指令而没有这个问题?
我刚刚解决了我的问题,这实际上非常令人失望。它是一个离子混合应用程序,我使用了 ui-router v0.2.13。在我的例子中,有一个 epub 阅读器(使用 epub.js)在我导航到我的图书库并选择任何其他书时不断报告“未找到文档”。当我重新加载浏览器书时,它被完美呈现,但是当我选择另一本书时,又遇到了同样的问题。
我的解决方法很简单。我刚刚从我的 LibraryController
中的 $state.go("app.reader", { fileName: fn, reload: true });
中删除了 reload:true
我在 angular-route@1.6.7
中遇到了同样的问题,这是因为正则表达式路径末尾的 extra slash:
.when('/goods/publish/:classId/', option)
至
.when('/goods/publish/:classId', option)
它工作正常。
只需在此处添加我的案例:
我在 $state.go('new_state', {foo: "foo@bar"})
中使用 angular-ui-router
将 encodeURIComponent 添加到参数后,问题就消失了:$state.go('new_state', {foo: encodeURIComponent("foo@bar")})
。
发生了什么? URL 中不允许参数值中的字符“@”。结果,angular-ui-router 两次创建了我的控制器:在第一次创建期间它传递了原始的“foo@bar”,在第二次创建期间它将传递编码版本“foo%40bar”。一旦我如上所示明确编码参数,问题就消失了。
我的问题真的很难追查。最后,当网页缺少图像时,问题就出现了。 src 缺少 URL。这发生在 MVC 5 Web 控制器上。为了解决这个问题,当没有真实图像可用时,我包含了透明图像。
<img alt="" class="logo" src="">
我发现我的被调用了两次是因为我从我的 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() 被调用两次。希望它可以帮助某人。
不定期副业成功案例分享
<div ng-view>...
更改为<div class="ng-view">...
时,这个问题就停止了。我以前没有遇到过这种行为,但也许其他人也有这种行为。