默认情况下,当您按下浏览器中的后退按钮以转到先前状态时,似乎会重新加载先前状态的控制器.(在亲子国家的情况下不是这样)
我怎样才能防止这种情况发生?
由于我不会更改当前状态中可能影响先前状态的任何数据,因此我不希望先前的状态再次重新加载.
这是一个小型的plunker: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
在这种情况下)正在做一些可视化,需要一些时间再次创建.
让我们从一个全局控制器开始,像是GlobalCtrl
添加到或
标签之类的
ng-controller="GlobalCtrl
.
这样做将使我们能够在GlobalCtrl
整个单页Angular应用程序中保持这个范围(因为您使用的是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中引用的范围以及我们在State控制器中使用的范围,它们是如何相关的?
嗯,这是一个非常好的问题,但它很简单.每次在Angular中创建新范围时,它总是继承其父范围(除非隔离).所以,当你的home
状态控制器实例化,使用父状态,即其范围内创建$rootScope
在这种情况下,在这里,我们的实例globalData
中$rootScope
这是一个对象(Object
在Javascript可用于它的任何嵌套的对象.阅读).所以,现在当我们设置globalData.preventExecution
true/false
,同样的数据可以在使用$scope
你的home
状态控制器.这是两个范围相关或使用相同数据的方式.
回答问题:ui-router中是否有一些标志或设置可以实现这一点
如果您想为多个状态实现上述行为代码,那么您可以编写如下内容:
$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
你想要的旗帜.