Modal Popups in AngularJS using angular-ui-router ($stateProvider) without updating the browser url

孤街醉人 提交于 2019-12-12 05:27:54

问题


My criteria was:

  1. Open a modal from anywhere in my app
  2. Don't rewrite the url, leave it as is from before opening the modal
  3. When pressing the back button on the browser don't remember modal states and reopen them
  4. Don't include lots of options in the markup when ui-sref is being used

I'm using $stateProvider in my angularjs application to handle the routing - I love how easy it is to display a modal using ui-sref element attributes along with onEnter event in the .state function.

The issue I'm having is that I want to be able to display a modal over the top of any page in my application without it redirecting to the route for the modal popup.

Currently I'm using transitionTo to get back to the previous state before the modal was opened but it's messy and you can see the page changing behind the modal mask.

Does anyone know how to create true global modals using $stateProvider or will I have to run my own modal manager to deal with it. I already have this in place for Confirmation dialogues but it's a little messy as I have many ng-clicks throughout the markup and $scope.click = function in many controllers along with $on and $broadcast / $emit events - which I don't want (if I can help it).

UPDATE 15/10/15

When transitioning to the model states I also don't want the url to change / store the state in the browsers back history.

UPDATE 15/10/15 - 30 minutes after previous update

I managed to work it out - see answer below.


回答1:


I worked it out.

I have the following state:

$stateProvider.state("default.mychannels.modalpopup", {
        url: 'XXX',
        data: { isModal: true },
        onEnter: ['$stateParams', '$state', '$modal', function ($stateParams, $state, $modal) {
            modal = $modal.open({
               ...
            });
        }],
        onExit: function () {
            modal.close();
        }
    });

As you can see, I'm setting a data property stating whether this state is a modal or not.

Then in the $stateChangeStart event I do the following:

  $rootScope.$on('$stateChangeStart', function (event, to, toParams, from, fromParams) {

        var isModal = false;

        if (to.data != undefined) {
            isModal = to.data.isModal == undefined ? false : to.data.isModal;
        }

        if (isModal) {
            event.preventDefault();
            $state.go(to, toParams, {
                location: false, notify: false
            });

        } else {

            var requiresAuth = to.data && to.data.requiresAuth;
            var isAuthenticated = authenticationService.isLoggedIn();
            if (requiresAuth) {
                if (!isAuthenticated) {
                    event.preventDefault();

                    event.currentScope.loginConfirmedState = to.name;
                    event.currentScope.loginConfirmedStateParams = toParams;

                    // user is not logged in
                    $rootScope.$broadcast('event:auth-loginRequired');
                }
            } else {
                $rootScope.$broadcast('event:auth-loginNotRequired');
            }
        }
        $rootScope.previousState = from;
        $rootScope.previousStateParams = fromParams;

    });

The key part of this code snippet, apart from picking up the isModal data property, are the properties were are providing to the go function.

$state.go(to, toParams, {
                location: false, notify: false
            });

You need to set location to false within the $state.go options - this will not update the browser url (and therefore will not go into the browsers back history).

You also need to set notify to false within the $state.go options - this will prevent the $stateProvider being called again due to $state.go being called from within it. This will prevent an infinite loop.

Pretty simple, but I had a hard time finding a solution but eventually worked it out.



来源:https://stackoverflow.com/questions/33146314/modal-popups-in-angularjs-using-angular-ui-router-stateprovider-without-updat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!