2014-05-05 60 views
6

我正在使用UI-Router和angular bootstrap-ui。我有一個狀態設置來創建模式'​​onEnter'。當我試圖關閉模式'onExit'時,我現在遇到了問題。這是基本狀態。當輸入'items.detail'時它會打開一個模式,當模式關閉或解散時它將轉換爲'項目'。需要關閉狀態退出模式

.state('items.detail', { 
    url: '/{id}', 
    onEnter: function ($stateParams, $state, $modal, $resource) { 
     var modalInstance = $modal.open({ 
      templateUrl: 'views/modal/item-detail.html', 
      controller: 'itemDetailCtrl' 
     }) 
     .result.then(function() { 
      $state.transitionTo('items'); 
     }, function() { 
      $state.transitionTo('items'); 
     }); 
    } 
}) 

我試過使用onExit處理程序就像這樣。但是無法訪問modalInstance或模式從該處理程序中獲取的作用域。我試圖注入的一切都是未定義的。

.state('items.detail', { 
    url: '/{id}', 
    onEnter: function ($stateParams, $state, $modal, $resource) { 
     var modalInstance = $modal.open({ 
      templateUrl: 'views/modal/item-detail.html', 
      controller: 'itemDetailCtrl' 
     }) 
     .result.then(function() { 
      $state.transitionTo('items'); 
     }, function() { 
      $state.transitionTo('items'); 
     }); 
    }, 
    onExit: function ($scope) { 
     controller: function ($scope, $modalInstance, $modal) { 
      $modalInstance.dismiss(); 
     }; 
    } 
}) 

從我的模態的控制器我試着聽狀態的變化。

$scope.$on('$stateChangeStart', function() { 
    $modalInstance.dismiss(); 
}); 

我既$範圍嘗試這樣做。$上$ rootScope。$上這兩個工作,但他們最終會被調用的任何國家之間的每一次我的轉變。然而,只有在我打開模式後纔會發生這種情況。

如果最後一點不清楚......當我刷新我的角度應用程序時,我可以在所有其他狀態之間進行轉換,但不會調用此偵聽器事件,但在打開該模式後,所有狀態更改都會被調用聽衆,即使在模式關閉後。

回答

3

我認爲你可以更好地組織你的模態打開行爲。我不會在狀態定義中使用onEnter和onExit處理程序。相反,它是更好地定義控制器,它應該處理模式:

.state('items.detail', { 
    url: '/{id}', 
    controller:'ItemDetailsController', 
    template: '<div ui-view></div>' 
}) 

然後定義你的控制器:

.controller('ItemDetailsController', [ 
    function($stateParams, $state, $modal, $resource){ 
     var modalInstance = $modal.open({ 
      templateUrl: 'views/modal/item-detail.html', 
      controller: 'ModalInstanceCtrl', 
      size: size, 
      resolve: { 
       itemId: function() { 
        return $stateParams.id; 
      } 
     modalInstance.result.then(function() { 
       $state.go('items'); 
      }, function() { 
       $state.go('items'); 
     }); 
     } 
    });  
    } 
]) 

然後定義您的ModalInstanceCtrl:

.controller('ModalInstanceCtrl', [ 
    function ($scope, $modalInstance, itemId) { 

     //Find your item from somewhere using itemId and some services 
     //and do your stuff 


     $scope.ok = function() { 
      $modalInstance.close('ok'); 
     }; 

     $scope.cancel = function() { 
      $modalInstance.dismiss('cancel'); 
     }; 
    }; 
]); 

這樣,你模態將被關閉在ModalInstanceCtrl中,你不會擔心狀態的onExit處理函數。

關於在$ scope上添加的監聽器。看起來你添加了監聽器,並且在你的狀態發生變化時永遠不會刪除它,這會導致內存泄漏,並且每次你的應用改變狀態時都會執行處理函數!所以最好擺脫那個事件監聽器,因爲你實際上並不需要它。

+1

謝謝,這似乎是一個更好的解決方案,並且很容易實現。 – Constellates

+0

歡迎,祝你好運:) – Armen

+0

等待,我想在這個瞬間,我誤解了發生了什麼。現在我下班回家了,它並沒有關閉狀態改變的模式,我猜測它從來沒有或者我改變過一些東西。無論如何,當這個狀態離開時,什麼部分會關閉模態? – Constellates

2

您可以防止離開狀態通過偵聽$stateChangeStart event

$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ 
    console.log('$stateChangeStart', toState); 
    if (toState.name != 'items.list'){ 
     event.preventDefault(); 
     var top = $modalStack.getTop(); 
     if (top) { 
      $modalStack.dismiss(top.key); 
     } 
     $state.go('items.list'); 
    } 
}); 
+0

所有這些事件都是在$ rootScope級別觸發的[cit。] – YoBre

5

雖然這個問題是很老,因爲我遇到了同樣的情況最近,和更好的解決方案來了,我決定分享無論如何,我的結果。關鍵是將$ modal.open服務移動到狀態的一部分,這是一種預加載數據和$ promise服務,然後將已解析的modelInstance注入onEnter,onExit等。代碼可能如下所示:

.state('items.detail', { 
    url: '/{id}', 
    resolve: { 
     modalInstance: function(){ 
      return $modal.open({ 
       templateUrl: 'views/modal/item-detail.html', 
       controller: 'itemDetailCtrl' 
      }) 
     }, 
    }, 
    onEnter: function ($stateParams, $state, modalInstance, $resource) { 
     modalInstance 
     .result.then(function() { 
      $state.transitionTo('items'); 
     }, function() { 
      $state.transitionTo('items'); 
     }); 
    }, 
    onExit: function (modalInstance) { 
     if (modalInstance) { 
      modalInstance.close(); 
     } 
    } 
}) 
+1

這應該是可以接受的答案。 –