AngularJS:控制器在使用 UI 路由器更改状态时注册多次
AngularJS: Controllers registering multiple times when changing state with UI Router
我将 HTML 和 ui 视图注入 DOM,然后使用 ui.router 更改状态。每次状态更改时,该控制器似乎都会额外注册一次,因此控制器中的代码会执行多次。您可以在下面的 plnkr 中看到这方面的演示。 (只需弹出控制台,然后在左右按钮之间来回点击,注意每次点击控制器都会执行额外的时间。)
如果 ui-views 在 index.html 上作为静态内容存在,那么生活是美好的,问题就不会发生。仅当将它们注入 DOM.
时
var app = angular.module('app', ["ui.router", "appHome", "appOther"]).config([
"$urlRouterProvider", "$stateProvider", "$locationProvider",
function ($urlRouterProvider, $stateProvider, $locationProvider) {
$stateProvider.state('appHome', {
url: '/home/index',
views: {
"Alerts": {
template: 'THINGS',
controller: "AlertsController as Alerts",
}
}
}).state('appOther', {
url: '/other/index',
views: {
"Other": {
template: 'THINGS',
controller: "OtherController as Other",
}
}
});
}
]);
Plunker 上的测试用例:http://plnkr.co/edit/M2wzVLSSgZ7naOi58qgL
你为什么搞得这么复杂?您使用
有什么特殊原因吗
if(view == 'Alerts'){
view = '<div ui-view="Alerts"></div>';
state = 'appHome'
}
else{
view = '<div ui-view="Other"></div>';
state = 'appOther'
}
$('#test').html($compile(view)(scope));
$state.go(state);
难道不能使用类似
的东西吗
<div ng-controller="MenuController">
<button ui-sref="appHome" value="CLick Me">GoTo Alerts</button>
<button ui-sref="appOther" value="CLick Me">GoTo Other</button>
</div>
<section ui-view></section>
我使用 ui-sref 在状态之间轻松导航。我准备了一个小演示来说明这一点。看看here。
这有帮助吗?可以用吗?这样你甚至不需要 menuController。
如果您需要命名视图(多个嵌套视图),请查看 documentation。解释得很好。你最终会得到类似的东西:
<!-- index.html -->
<body>
<div ui-view="alerts"></div>
<div ui-view="other"></div>
</body>
$stateProvider
.state('report', {
views: {
'alerts': { ... templates and/or controllers ... },
'other': {},
}
})
你快到了。 而且我不是在挑战或判断这种方法,只是提供答案。有a working example。
您已正确创建新范围。非常好。但这只是一个A。缺少基本的和常用的 B。 B - 与 A 相反 ===
销毁新作用域 (旧的).
这将为我们完成工作:
app.controller('MenuController', ["$scope","$compile", "$state","$http",
function MenuController($scope,$compile, $state, $http) {
$scope.goToUrl = function (view) {
// was scope previously created
var hasPreviousChildScope = this.childScope !== void 0
&& this.childScope !== null;
if(hasPreviousChildScope)
{
// we must clear after ourselves
this.childScope.$destroy();
this.childScope = null;
}
// create new scope
this.childScope = $scope.$new();
var html;
var state;
if(view == 'Alerts'){
view = '<div ui-view="Alerts"></div>';
state = 'appHome'
}
else{
view = '<div ui-view="Other"></div>';
state = 'appOther'
}
$('#test').html($compile(view)(this.childScope));
$state.go(state);
};
}
]);
检查所有 in action here
我将 HTML 和 ui 视图注入 DOM,然后使用 ui.router 更改状态。每次状态更改时,该控制器似乎都会额外注册一次,因此控制器中的代码会执行多次。您可以在下面的 plnkr 中看到这方面的演示。 (只需弹出控制台,然后在左右按钮之间来回点击,注意每次点击控制器都会执行额外的时间。)
如果 ui-views 在 index.html 上作为静态内容存在,那么生活是美好的,问题就不会发生。仅当将它们注入 DOM.
时var app = angular.module('app', ["ui.router", "appHome", "appOther"]).config([
"$urlRouterProvider", "$stateProvider", "$locationProvider",
function ($urlRouterProvider, $stateProvider, $locationProvider) {
$stateProvider.state('appHome', {
url: '/home/index',
views: {
"Alerts": {
template: 'THINGS',
controller: "AlertsController as Alerts",
}
}
}).state('appOther', {
url: '/other/index',
views: {
"Other": {
template: 'THINGS',
controller: "OtherController as Other",
}
}
});
}
]);
Plunker 上的测试用例:http://plnkr.co/edit/M2wzVLSSgZ7naOi58qgL
你为什么搞得这么复杂?您使用
有什么特殊原因吗if(view == 'Alerts'){
view = '<div ui-view="Alerts"></div>';
state = 'appHome'
}
else{
view = '<div ui-view="Other"></div>';
state = 'appOther'
}
$('#test').html($compile(view)(scope));
$state.go(state);
难道不能使用类似
的东西吗<div ng-controller="MenuController">
<button ui-sref="appHome" value="CLick Me">GoTo Alerts</button>
<button ui-sref="appOther" value="CLick Me">GoTo Other</button>
</div>
<section ui-view></section>
我使用 ui-sref 在状态之间轻松导航。我准备了一个小演示来说明这一点。看看here。 这有帮助吗?可以用吗?这样你甚至不需要 menuController。
如果您需要命名视图(多个嵌套视图),请查看 documentation。解释得很好。你最终会得到类似的东西:
<!-- index.html -->
<body>
<div ui-view="alerts"></div>
<div ui-view="other"></div>
</body>
$stateProvider
.state('report', {
views: {
'alerts': { ... templates and/or controllers ... },
'other': {},
}
})
你快到了。 而且我不是在挑战或判断这种方法,只是提供答案。有a working example。
您已正确创建新范围。非常好。但这只是一个A。缺少基本的和常用的 B。 B - 与 A 相反 ===
销毁新作用域 (旧的).
这将为我们完成工作:
app.controller('MenuController', ["$scope","$compile", "$state","$http",
function MenuController($scope,$compile, $state, $http) {
$scope.goToUrl = function (view) {
// was scope previously created
var hasPreviousChildScope = this.childScope !== void 0
&& this.childScope !== null;
if(hasPreviousChildScope)
{
// we must clear after ourselves
this.childScope.$destroy();
this.childScope = null;
}
// create new scope
this.childScope = $scope.$new();
var html;
var state;
if(view == 'Alerts'){
view = '<div ui-view="Alerts"></div>';
state = 'appHome'
}
else{
view = '<div ui-view="Other"></div>';
state = 'appOther'
}
$('#test').html($compile(view)(this.childScope));
$state.go(state);
};
}
]);
检查所有 in action here