2015-12-18 42 views
8

默認情況下,當您按下瀏覽器中的後退按鈕以轉到先前狀態時,將重新加載先前狀態的控制器。 (親子狀態不適用)Angular UI路由器:在按下瀏覽器中的後退按鈕時重新加載控制器

我該如何防止這種情況發生?

由於我不打算改變當前狀態下可能影響前一狀態的任何數據,我不希望以前的狀態重新加載。

這裏是一個小plunker: http://plnkr.co/edit/xkQcEywRZVFmavW6eRGq?p=preview

有2種狀態:homeabout。如果你進入about狀態,然後按回來按鈕,你會看到home狀態控制器被再次調用。

.state('home', { 
    url: '/home', 
    templateUrl: 'partial-home.html', 
    controller: function($scope) { 
     console.log('i was called'); 
    } 
}) 

我相信這是預期的行爲,但我想阻止它,因爲我以前的狀態(home在這種情況下)正在做一些可視化這需要一些時間來重新創建。

回答

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中創建一個新範圍時,它總是繼承它的父範圍(除非被隔離)。所以當你的狀態控制器實例化時,它的作用域就是使用父狀態創建的,例如$rootScope這裏是我們在這裏實例化globalData$rootScope這是一個對象(Javascript中的Object可以用於它的任何嵌套對象Read this)。因此,現在當我們設置globalData.preventExecutiontrue/false時,可以在home狀態控制器的$scope中使用相同的數據。這是兩個範圍如何相關或使用相同的數據。

問題的答案有一些標誌或設置在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作爲你想要的標誌。

+2

刪除我的答案,因爲這一個更詳細。 – user3632710

+1

它正在工作。但我不能理解一件事,我們在GlobalCtrl中提到的範圍和我們在州控制器中使用的範圍,它們是如何相關的?似乎同樣的作用域被注入到狀態控制器中,還是因爲rootScope被繼承? – gaurav5430

+0

另外,這段代碼非常特別,我必須爲許多狀態交互寫這樣的東西,是否有一些標誌或設置在UI路由器可以實現這一點。例如,不管是什麼狀態,都不要重新加載控制器。 – gaurav5430

相關問題