如何处理 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 帮助获得此解决方案。
我希望我的 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 帮助获得此解决方案。