需要在状态退出时关闭模态

Con*_*tes 7 javascript angularjs

我正在使用UI-Router和angular bootstrap-ui.我有一个状态设置来创建模态'onEnter'.当我试图关闭模态'onExit'时,我现在遇到了问题.这是基本状态.当输入'items.detail'时它将打开一个模态,当该模态被关闭或解除时它将转换为'items'.

.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');
        });
    }
})
Run Code Online (Sandbox Code Playgroud)

我试过像这样使用onExit处理程序.但是无法从该处理程序访问modalInstance或modal所在的范围.我尝试注射的所有东西都是未定义的.

.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();
        };
    }
})
Run Code Online (Sandbox Code Playgroud)

从我的模态控制器中我试着听取状态变化.

$scope.$on('$stateChangeStart', function() {
    $modalInstance.dismiss();
});
Run Code Online (Sandbox Code Playgroud)

我已经用$ scope.$ on和$ rootScope.$ on尝试了这个,但是这两个都工作但是每次我在任何状态之间转换时它们都会被调用.这只会在我打开模态后发生.

如果最后一点不清楚...当我刷新我的角度应用程序时,我可以在所有其他状态之间进行转换而不会调用此侦听器事件但是在我打开该模态之后,所有状态更改都会被该侦听器调用,即使之后模态已关闭.

小智 7

虽然这个问题已经很老了,但最近我遇到了同样的情况,并提出了更好的解决方案,我决定在这里分享我的结果.关键点是将$ 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();
        }
    }
})
Run Code Online (Sandbox Code Playgroud)


小智 3

我认为你可以更好地组织你的模式打开行为。我不会在状态定义中使用 onEnter 和 onExit 处理程序。相反,最好定义应该处理模态的控制器:

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

然后定义你的控制器:

.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');
         });
      }
    });       
    }
])
Run Code Online (Sandbox Code Playgroud)

然后定义您的 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');
        };
    };
]);
Run Code Online (Sandbox Code Playgroud)

这样,模态将在 ModalInstanceCtrl 内关闭,并且您将不必担心状态的 onExit 处理程序。

关于在 $scope 上添加的侦听器。似乎当您添加侦听器并且在状态更改时从不删除它,这会导致内存泄漏,并且每次您的应用程序更改其状态时都会执行处理程序函数!因此,最好删除该事件侦听器,因为您实际上并不需要它。