2014-05-05 16 views
6

Używam UI-Routera i kątowego bootstrap-ui. Mam konfigurację stanu, aby utworzyć modalne "onEnter". Mam problemy teraz, gdy próbuję zamknąć modalny "onExit". Oto podstawowy stan. Otworzy modalny po wpisaniu "items.detail" i przejdzie do "pozycji", gdy ten modal jest zamknięty lub zwalniany.Konieczność zamknięcia modala przy wyjściu stanu

.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'); 
     }); 
    } 
}) 

Próbowałem już używać programu obsługi OnExit, jak w ten sposób. Ale nie były w stanie uzyskać dostępu do modalInstance lub zakresu, w którym modal jest z tego handlera. Wszystko, co próbuję wstrzyknąć, pojawia się nieokreślone.

.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(); 
     }; 
    } 
}) 

z kontrolera mojego modala Próbowałem słuchać zmian stanu.

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

Próbowałem to zarówno z zakresu $. $ I $ na rootScope. $ I na obu tych prac, ale w końcu jest wywoływana za każdym razem, gdy przejście między dowolnymi stanach. Zdarza się to jednak dopiero po tym, jak otworzyłem modal.

W przypadku, gdy ten ostatni fragment jest niejasny ... Kiedy odświeżam swoją kanciastą aplikację, mogę przełączać się między wszystkimi moimi innymi stanami bez wywoływania tego zdarzenia słuchacza, ale po tym, jak otworzę ten modal, wszystkie moje zmiany stanu zostaną wywołane przez to słuchacza, nawet po zamknięciu modala.

Odpowiedz

3

Myślę, że możesz lepiej uporządkować swoje zachowanie otwarcia modów. Nie używałbym instrukcji obsługi wewnątrz i onExit wewnątrz definicji stanu. Zamiast tego lepiej określić kontroler, który powinien obsługiwać modalne:

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

Następnie zdefiniować Kontroler:

.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'); 
     }); 
     } 
    });  
    } 
]) 

następnie zdefiniować swoją 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'); 
     }; 
    }; 
]); 

W ten sposób modalnych będą zamknięte w ramach ModalInstanceCtrl, a nie będziesz się martwić o obsługę programu onExit w stanie.

Informacje o detektorze dodane w $ scope. Wydaje się, gdy dodajesz słuchacza i nigdy go nie usuwasz, gdy zmienia się twój stan, to powoduje wyciek pamięci i funkcję obsługi jest wykonywana za każdym razem, gdy twoja aplikacja zmienia swój stan! Więc lepiej pozbyć się tego detektora zdarzeń, ponieważ nie jest on potrzebny.

+1

Dziękuję, to wydaje się być o wiele lepszym rozwiązaniem i było łatwe do wdrożenia. – Constellates

+0

Witaj, powodzenia :) – Armen

+0

Czekajcie, myślę, że w ogniu chwili źle zrozumiałem, co się dzieje. Teraz, gdy jestem w domu z pracy, nie zamyka się modalności na zmiany stanu, domyślam się, że to nigdy nie było lub coś zmieniłem. W każdym razie, jaka część tego by zamykać modal kiedy stan jest zostawiony? – Constellates

2

Można zapobiec opuszczeniu stanu słuchając dla $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

Wszystkie te zdarzenia są uruchamiane na poziomie $ rootScope. [cit.] – YoBre

5

Choć pytanie jest dość stary, jak wpadłem na tej samej sytuacji w ostatnim czasie, a wymyślił lepszego rozwiązania, postanowiłem podzielić moje wyniki tutaj i tak. Kluczową sprawą jest przeniesienie usługi $ modal.open na część stanu, która jest rodzajem wstępnych danych obciążenia i obietnicami $, a następnie wstawienie rozwiązanej metody modelIn do programu onEnter, onExit itd. Kody mogą wyglądać następująco :

.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

To powinna być akceptowana odpowiedź, która spełnia dokładnie to, czego poszukiwał autor –

Powiązane problemy