默认情况下,当您按下浏览器中的后退按钮以转到先前状态时,会重新加载先前状态的控制器。 (在亲子国家的情况下不是这样)
如何防止这种情况发生?
由于我不会更改当前状态中可能影响先前状态的任何数据,因此我不希望先前的状态再次重新加载。
这是一个小掠夺者: http://plnkr.co/edit/xkQcEywRZVFmavW6eRGq?p=preview
有两种状态:home
和about
。如果您转到about
状态,然后按回按钮,您将看到再次调用home
状态控制器。
.state('home', {
url: '/home',
templateUrl: 'partial-home.html',
controller: function($scope) {
console.log('i was called');
}
})
我相信这是预期的行为,但我想阻止它,因为我之前的状态(在这种情况下为home
)正在做一些可视化,需要一些时间再次创建。
答案 0 :(得分:6)
让我们从像GlobalCtrl
这样的全局控制器开始,该控制器已添加到<body>
或<html>
标记,例如ng-controller="GlobalCtrl
。
这样做可以让我们在整个单页Angular应用中保持此GlobalCtrl
的范围(就像使用ui-router一样)。
现在,在GlobalCtrl
内定义如下内容:
$rootScope.globalData = {preventExecution: false};
// This callback will be called everytime you change a page using ui-router state
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
$scope.globalData.preventExecution = false;
// Just check for your states here
if (toState.name == "home" && fromState.name == "about") {
$scope.globalData.preventExecution = true;
}
});
现在,在您的州配置中,您可以使用此$scope.globalData.preventExecution;
.state('home', {
url: '/home',
templateUrl: 'partial-home.html',
controller: function($scope) {
if ($scope.globalData.preventExecution) {
return;
}
console.log('i was called');
}
});
回答问题:我们在GlobalCtrl中引用的范围以及我们在状态控制器中使用的范围,它们是如何相关的?
嗯,这是一个非常好的问题,但很简单。每次在Angular中创建新范围时,它总是继承其父范围(除非隔离)。因此,当您的home
状态控制器实例化时,在此情况下使用父状态(即$rootScope
)创建其范围,并且我们将globalData
中的$rootScope
实例化为对象({1}} Javascript中的Object
可以用于任何嵌套对象。Read this)。现在,当我们设置globalData.preventExecution
true/false
时,可以在$scope
状态控制器的home
中使用相同的数据。这就是两个范围相关或使用相同数据的方式。
回答问题: ui路由器中是否有一些标记或设置可以完成此操作
如果您想为多个状态实现上述行为代码,那么您可以编写如下内容:
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState) {
$scope.globalData.preventExecution = false;
if (toState.name == "home" && fromState && fromState.preventHomeReExecution) {
$scope.globalData.preventExecution = true;
}
});
现在,您的州可以这样写:
.state('about', {
url: '/about',
templateUrl: 'partial-about.html',
preventHomeReExecution: true
})
.state('foo', {
url: '/foo',
templateUrl: 'partial-foo.html',
})
.state('bar', {
url: '/bar',
templateUrl: 'partial-bar.html'
preventHomeReExecution: true
})
基本上,我们使用preventHomeReExecution: true
作为你想要的旗帜。