离子 - 何时应该调用ionicModal.remove()? [Ionic Modal Hide Callback]

时间:2016-03-11 05:48:16

标签: javascript angularjs ionic-framework

在我的控制器中,通过监听$ionicView.afterEnter事件,工厂初始化模态视图。正如documentation建议的那样,只要当前的活动离子视图即将被销毁,就应该删除模态视图。在$ionicView.beforeLeave回调中调用函数以删除模态视图。

.controller('UserProfileCtrl', function($scope, $state, user, ModalFactory) {
    $scope.user = user;

    $scope.checkOrders = function() {
        $state.go('app.orders');
    };

    $scope.$on('$ionicView.afterEnter', function() {
        $scope.modals = ModalFactory.getUserProfileModals($scope, user.photos);
    });

    $scope.$on('$ionicView.beforeLeave', function() {
        $scope.modals.remove();
    });
});

.factory('ModalFactory', function($ionicModal, $ionicSlideBoxDelegate) {
    var modalFactory = {};

    modalFactory.getUserProfileModals = function(scope, images) {
        var modals = {
            'views': [],
            'data': []
        };

        $ionicModal.fromTemplateUrl('templates/modals/common/image-view.html', { 'scope': scope }).then(function(modal) { modals.views.imageView = modal; });

        if (images) {
            modals.data.images = images;
        }

        modals.open = function(view, slide) {
            Object.keys(this.views).forEach(function(key, index) {
                console.log(key);
            });

            if (view && this.views.hasOwnProperty(view)) {
                this.views[view].show();

                if (view == 'imageView' && slide) {
                    $ionicSlideBoxDelegate.$getByHandle('image-view').slide(slide);
                }
            }
        };

        modals.close = function(view) {
            Object.keys(this.views).forEach(function(key, index) {
                console.log(key);
            });

            if (view && this.views.hasOwnProperty(view)) {
                this.views[view].hide();
            } else {
                Object.keys(this.views).forEach(function(key, index) {
                    this.views[key].hide();
                });
            }
        };

        modals.remove = function() {
            console.log('remove');
            Object.keys(this.views).forEach(function(key, index) {
                console.log(key);
            });

            this.data.splice(0, this.data.length);

            Object.keys(this.views).forEach(function(key, index) {
                this.views[key].remove();
            });

            this.views.splice(0, this.views.length);
        };

        return modals;
    };

    return modalFactory;
});

但是,当我按顺序执行这些操作时,我在控制台中得到以下输出:

  1. 致电$scope.modals.open('imageView', 1)
  2. 致电$scope.modals.close()
  3. 使用$state.go('app.orders')导航到另一个页面。
  4. Screenshot showing console output

    我尝试收听$destroy而不是$ionicView.beforeLeave,但后来根本没有调用$scope.modals.remove()。当我使用Chrome测试我的应用程序时,似乎$destroy没有被触发。

    有谁能告诉我什么时候应该删除模态视图,为什么在我的场景中会出现这样的错误消息?

    更新

    我按如下方式修改了ModalFactory中的代码后,错误就消失了。

    function open(view, slide) {
        if (view && modals.views.hasOwnProperty(view)) {
            modals.views[view].show();
    
            if (view == 'imageView' && slide) {
                $ionicSlideBoxDelegate.$getByHandle('image-view').slide(slide);
            }
        }
    };
    
    function close(view) {
        if (view && modals.views.hasOwnProperty(view)) {
            modals.views[view].hide();
        } else {
            Object.keys(modals.views).forEach(function(key, index) {
                modals.views[key].hide();
            });
        }
    };
    
    function remove() {
        console.log('remove');
    
        modals.data.splice(0, modals.data.length);
    
        Object.keys(modals.views).forEach(function(key, index) {
            modals.views[key].remove();
        });
    
        modals.views.splice(0, modals.views.length);
    };
    
    modals.open = open;
    modals.close = close;
    modals.remove = remove;
    
    return modals;
    

2 个答案:

答案 0 :(得分:2)

通过使用$ scope。$ on('$ destroy',..)方法,Angular将在拆除范围并从其父级删除范围之前广播$ destroy事件。

这是我如何解决modal.remove()问题的例子,

.factory('ModalFactory', function($ionicModal, $rootScope) {
    var init = function(tpl, $scope) {
        var promise;
        $scope = $scope || $rootScope.$new();

        promise = $ionicModal.fromTemplateUrl(tpl, {
            scope: $scope,
            animation: 'slide-in-right'
        }).then(function(modal) {
            $scope.modal = modal;
            return modal;
        });

        $scope.openModal = function() {
            $scope.modal.show();
        };
        $scope.closeModal = function() {
            $scope.modal.hide();
        };
        $scope.$on('$destroy', function() {
            $scope.modal.remove();
        });

        return promise;
    };

    return {
        init: init
    }

})

从控制器传递控制器和模态模板的当前范围

.controller('UserProfileCtrl', function($scope, $state, user, ModalFactory) {    
    ModalFactory.init('image-view.html', $scope)
            .then(function(modal) {
                confirmationModal = modal;
                confirmationModal.show();
            });
})

希望这对你有所帮助。

答案 1 :(得分:0)

由于我在2016年寻找解决方案,所以提到了

  

$ scope。$ on(' destroy')在新的离子构建中被调用,其中缓存是   使用

所以我提出了一个解决方案,在modal.hidden上为动画/转换结束添加事件监听器。

首先, solution 解决了动画结束事件的问题。

这个很棒的家伙创建了两个库,一个是jQuery Depency,另一个是用简单的javascript编写的。

jQuery插件:

/*
    By Osvaldas Valutis, www.osvaldas.info
    Available for use under the MIT License
*/

;( function( $, window, document, undefined )
{
    var s = document.body || document.documentElement, s = s.style, prefixAnimation = '', prefixTransition = '';

    if( s.WebkitAnimation == '' )   prefixAnimation  = '-webkit-';
    if( s.MozAnimation == '' )      prefixAnimation  = '-moz-';
    if( s.OAnimation == '' )        prefixAnimation  = '-o-';

    if( s.WebkitTransition == '' )  prefixTransition = '-webkit-';
    if( s.MozTransition == '' )     prefixTransition = '-moz-';
    if( s.OTransition == '' )       prefixTransition = '-o-';

    $.fn.extend(
    {
        onCSSAnimationEnd: function( callback )
        {
            var $this = $( this ).eq( 0 );
            $this.one( 'webkitAnimationEnd mozAnimationEnd oAnimationEnd oanimationend animationend', callback );
            if( ( prefixAnimation == '' && !( 'animation' in s ) ) || $this.css( prefixAnimation + 'animation-duration' ) == '0s' ) callback();
            return this;
        },
        onCSSTransitionEnd: function( callback )
        {
            var $this = $( this ).eq( 0 );
            $this.one( 'webkitTransitionEnd mozTransitionEnd oTransitionEnd otransitionend transitionend', callback );
            if( ( prefixTransition == '' && !( 'transition' in s ) ) || $this.css( prefixTransition + 'transition-duration' ) == '0s' ) callback();
            return this;
        }
    });
})( jQuery, window, document );

或使用 普通Javascript库:

/*
    By Osvaldas Valutis, www.osvaldas.info
    Available for use under the MIT License
*/

;( function ( document, window, index )
{
    var s = document.body || document.documentElement, s = s.style, prefixAnimation = '', prefixTransition = '';

    if( s.WebkitAnimation == '' )   prefixAnimation  = '-webkit-';
    if( s.MozAnimation == '' )      prefixAnimation  = '-moz-';
    if( s.OAnimation == '' )        prefixAnimation  = '-o-';

    if( s.WebkitTransition == '' )  prefixTransition = '-webkit-';
    if( s.MozTransition == '' )     prefixTransition = '-moz-';
    if( s.OTransition == '' )       prefixTransition = '-o-';

    Object.prototype.onCSSAnimationEnd = function( callback )
    {
        var runOnce = function( e ){ callback(); e.target.removeEventListener( e.type, runOnce ); };
        this.addEventListener( 'webkitAnimationEnd', runOnce );
        this.addEventListener( 'mozAnimationEnd', runOnce );
        this.addEventListener( 'oAnimationEnd', runOnce );
        this.addEventListener( 'oanimationend', runOnce );
        this.addEventListener( 'animationend', runOnce );
        if( ( prefixAnimation == '' && !( 'animation' in s ) ) || getComputedStyle( this )[ prefixAnimation + 'animation-duration' ] == '0s' ) callback();
        return this;
    };

    Object.prototype.onCSSTransitionEnd = function( callback )
    {
        var runOnce = function( e ){ callback(); e.target.removeEventListener( e.type, runOnce ); };
        this.addEventListener( 'webkitTransitionEnd', runOnce );
        this.addEventListener( 'mozTransitionEnd', runOnce );
        this.addEventListener( 'oTransitionEnd', runOnce );
        this.addEventListener( 'transitionend', runOnce );
        this.addEventListener( 'transitionend', runOnce );
        if( ( prefixTransition == '' && !( 'transition' in s ) ) || getComputedStyle( this )[ prefixTransition + 'transition-duration' ] == '0s' ) callback();
        return this;
    };
}( document, window, 0 ));

接下来在您的离子代码中,收听模态隐藏事件:

$scope.$on('modal.hidden', function() {
       $( '.modal' ).onCSSAnimationEnd( function()//this example uses jQuery Plugin
       {
           $scope.modal.remove();
       });
      });

或简单的Javascripy示例:

var item = document.querySelector( '.modal' );   
item.onCSSAnimationEnd( function()
{
    $scope.modal.remove();
});

希望有一天能帮到某人。