te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Need to close a modal on state exit - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Need to close a modal on state exit - Stack Overflow

programmeradmin5浏览0评论

I'm using UI-Router and angular bootstrap-ui. I have a state setup to create modal 'onEnter'. I'm having problems now when I'm trying to close the modal 'onExit'. Here is the basic state. It will open a modal when 'items.detail' is entered and it will transitions to 'items' when that modal is closed or dismissed.

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

I've tried using the onExit handler like so. But haven't been able to access the modalInstance or the scope that the modal is in from that handler. Everything I try to inject es up undefined.

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

from within my modal's controller I've tried listening for state changes.

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

I've tried this with both $scope.$on and $rootScope.$on and both of these work but they end up being called every time I transition between any states. This only happens however after I've opened the modal.

In case this last bit is unclear... When I refresh my angular app I can transition between all my other states with out this listener event being called but after I open that modal all of my state changes get called by that listener, even after the modal is closed.

I'm using UI-Router and angular bootstrap-ui. I have a state setup to create modal 'onEnter'. I'm having problems now when I'm trying to close the modal 'onExit'. Here is the basic state. It will open a modal when 'items.detail' is entered and it will transitions to 'items' when that modal is closed or dismissed.

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

I've tried using the onExit handler like so. But haven't been able to access the modalInstance or the scope that the modal is in from that handler. Everything I try to inject es up undefined.

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

from within my modal's controller I've tried listening for state changes.

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

I've tried this with both $scope.$on and $rootScope.$on and both of these work but they end up being called every time I transition between any states. This only happens however after I've opened the modal.

In case this last bit is unclear... When I refresh my angular app I can transition between all my other states with out this listener event being called but after I open that modal all of my state changes get called by that listener, even after the modal is closed.

Share Improve this question asked May 5, 2014 at 19:37 ConstellatesConstellates 2,1134 gold badges19 silver badges29 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 7

Although the question is quite old, as I ran into the same situation recently, and came up with a better solution, I decided to share my results here anyway. The key point is to move the $modal.open service into resolve part of the state, which is kind of pre-load data and $promise services, and then inject the resolved modelInstance into onEnter, onExit etc. Codes might looks like as follow:

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

I think you can better organize your modal opening behavior.I would not use onEnter and onExit handlers inside state definition. Instead it's better to define controller which should handle modal:

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

Then define your controller:

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

Then define your 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');
        };
    };
]);

In this way you modal will be closed within ModalInstanceCtrl, and you will not worry about state's onExit handler.

About listener added on $scope. Seems when you add the listener and never remove it whenever your state changes, this is causing memory leak and handler function gets executed every time your app changes his state! So it's better to get rid of that event listener as you don't need it actually.

You can prevent leaving the state by listening for the $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)

  1. 暂无评论