AngularJS 中的模态弹出窗口使用 angular-ui-router ($stateProvider) 而不更新浏览器 url [英] Modal Popups in AngularJS using angular-ui-router ($stateProvider) without updating the browser url

查看:14
本文介绍了AngularJS 中的模态弹出窗口使用 angular-ui-router ($stateProvider) 而不更新浏览器 url的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的标准是:

  1. 从我的应用中的任何位置打开一个模态
  2. 不要重写网址,在打开模态之前保持原样
  3. 按下浏览器上的后退按钮时,不要记住模态状态并重新打开它们
  4. 在使用 ui-sref 时不要在标记中包含大量选项

我在我的 angularjs 应用程序中使用 $stateProvider 来处理路由 - 我喜欢使用 ui-sref 元素属性以及 .state 函数中的 onEnter 事件来显示模式是多么容易.

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.

目前我正在使用 transitionTo 返回到打开模态之前的先前状态,但它很混乱,您可以看到页面在模态掩码后面发生变化.

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.

有谁知道如何使用 $stateProvider 创建真正的全局模态,或者我是否必须运行我自己的模态管理器来处理它.我已经为确认对话准备好了这个,但它有点乱,因为我在整个标记和 $scope.click = 中的许多控制器中都有很多 ng-clicks 以及 $on 和 $broadcast/$emit 事件 - 我没有'不想要(如果我能帮上忙的话).

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).

更新 15/10/15

UPDATE 15/10/15

当转换到模型状态时,我也不希望 url 更改/将状态存储在浏览器的历史记录中.

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

更新 15/10/15 - 上次更新后 30 分钟

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

我设法解决了 - 请参阅下面的答案.

I managed to work it out - see answer below.

推荐答案

我已经解决了.

我有以下状态:

$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.

然后在 $stateChangeStart 事件中我执行以下操作:

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;

    });

这个代码片段的关键部分,除了选择 isModal 数据属性,是提供给 go 函数的属性.

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

您需要在 $state.go 选项中将 location 设置为 false - 这不会更新浏览器 URL(因此不会进入浏览器的历史记录).

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).

您还需要在 $state.go 选项中将 notify 设置为 false - 这将防止 $stateProvider 由于 $state.go 在其中被调用而再次被调用.这将防止无限循环.

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.

这篇关于AngularJS 中的模态弹出窗口使用 angular-ui-router ($stateProvider) 而不更新浏览器 url的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆