如何处理 Angular 中任何可能路由上可选存在的查询字符串参数?

How to handle an optionally present query string parameter on any possible route in Angular?

我希望我的 angular 应用程序能够识别特定的查询字符串参数,而不管用户通过哪条路径进入该应用程序。当我的应用程序完成所有必须做的事情时,我想向用户提供一个选项,让他们 return 到他们最初打算访问的网站。

一个典型的用例是想像某人试图访问一个站点上受保护的 URL,被重定向到身份提供者,被识别然后被 returned 到该站点他们最初试图访问。

例如,用户可以在应用中使用以下任何路线:

https://any.doma.in/#/a?returnTo="https://origin.al/url"
https://any.doma.in/#/b?returnTo="https://origin.al/url"
https://any.doma.in/#/c?returnTo="https://origin.al/url"

我可以创建一个服务,该服务将在我的应用程序中定义的每个可能的路线中使用,该服务将查找参数并存储它,但我不想在每个定义的路线中复制该代码。

有没有办法创建一个始终为每条路线处理的路线定义,查找参数,然后将程序流释放到我的应用程序中的原始路线?

您需要的是一个可以在每次 URL 更改时检查该参数的地方。由于 .config 方法仅被调用一次(当应用程序被...错误.. 配置时),您可以改用 .运行 方法。

因此,我们假设您的查询项名为 returnTo。我喜欢这听起来的方式。

我假设您有一个类似于此的 routeProvider 配置调用:

YourAngularApp.config(['$routeProvider', function ($route) {

.... code for routes here ....


}]);

并且,假设您调用了如下所示的服务:

https://any.doma.in/#/a?returnTo=https://origin.al/url

糟糕...等等。那行不通的。那个小“?”在您的# ... 之后出现,因此浏览器实际上会及时返回。它实际上会向后移动 2 秒,并让您永远处于同一个程序员循环中,除非您打破循环并恢复宇宙的正确秩序。除非你这样做,否则你将像 pear-shaped Sisyphus 一样被困在 Aeron 中。

https://any.doma.in/?returnTo=https%3A%2F%2Forigin.al%2Furl%0D%0A#/a

好的。感觉好一点了。怎么办?好吧……回到上面的 .config 调用。我们可以将 .运行 方法调用附加到该文件的底部:

YourAngularApp.run(['$rootScope','$location', function($rootScope, $location) {

    $rootScope.$on('$locationChangeStart', function (event, newUrl, oldUrl) {
        var myParameterValue = getParameterByName('returnTo');
        if(myParameterValue != '') {
            $rootScope.returnTo = myParameterValue;
            //do whatever it is you want to do with that parameter here.
        }
    });

    function getParameterByName(name) {
        name = name.replace(/[\[]/, "\[").replace(/[\]]/, "\]");
        var regex = new RegExp("[\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
        return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
    }

}]);

请注意,我正在添加一个我取消 from here 的小 getParam 方法,因为

(a) 认为代码应该在 post 和

中完成

(b) 我假设您不想在每个 angular 路由和

中将该参数作为可选参数包含在内

(c) 我假设您讨厌 jQuery(似乎在 angular 社区中流传着很多)。

不确定您需要做什么,但我猜您可以查看 $rootScope 中的设置,以确定对 returnTo 采取哪些步骤...这将使您在同一时间获得该参数的值代码块作为 $rootScope 和 $location ...你应该可以从这里拿走它!

而且 - 这让您无需记住将其编码到应用程序的每条路线中即可访问!只是不要忘记上面讨厌的 url 格式化内容。祝你好运!

期待以下 url:https://any.doma.in/#/a?returnTo="https://origin.al/url"

可以像这样在应用加载时检索该值:

angular
    .module('app.module')
    .run(lookForParameter);

function lookForParameter($rootScope, returnToService, $location) {
    $rootScope.$on('$locationChangeStart', function() {
        var search = $location.search();

        if (search.returnTo && angular.isString(search.returnTo)) {
            returnToService.url = search.returnTo;
        }
    });
}

感谢@bri 帮助获得此解决方案。