在AngularJS应用中,把URL传递给$routeParam
Pass URL to as $routeParam in AngularJS app
如何将实际URL(使用斜杠,逗号等)作为$routeParam传递给AngularJS应用程序?
这将工作:http://paprikka.github.io/le-bat//预览/asdadasda
这不会:http://paprikka.github.io/le-bat//预览/http://page.com
也不会:http://paprikka.github.io/le-bat//预览/http % 3 a % 2 f % 2 fpage.com
或:url http://paprikka.github.io/le-bat//预览/? 3 = http % % 2 f % 2 fpage.com
详细信息AngularJS路由机制的设计不允许传递带有斜杠的字符串作为查询参数。我可以理解这个决定背后的原因——我们不想在这里创建一个无状态的服务器。但是,仍然有必要在路由中使用不同的分隔符或正则表达式。
我想创建一个应用程序,它接受url哈希字符串参数,并将其内容加载到iframe(链接在这里)。路由以非常标准的方式设置(我使用的是Coffeescript,但这段代码与纯js没有什么不同):
$routeProvider
.when('/preview/:src', {templateUrl: 'partials/preview.html',
controller: 'PreviewCtrl'})
.when('/preview', {templateUrl: 'partials/preview.html',
controller: 'PreviewCtrl'})
当然,我可以在AngularJS启动之前从哈希中加载url,然后将其传递给库,但如果我也可以在改变作用域内的数据时更新当前的路由参数,那就更好了——这就是为什么我认为最好不要避免使用AngularJS API。
在Angular 1.2中使用$routeProvider,你可以通过在模式中添加星号来传入位于路径末尾的url。不管你是否URLComponentEncode url,下面的代码都可以工作。
的路线:
angular.module('angularApp', ['ngRoute'])
.when('/frame/:picture_url*', {
templateUrl: 'views/frame.html',
controller: 'PictureFrame'
});
控制器:
.controller('PictureFrame', function($scope, $routeParams, $sce){
//whitelist the URL
$scope.picture_url = $sce.trustAsResourceUrl($routeParams.picture_url);
});
然后在你的模板中:
<iframe ng-src="{{picture_url}}"></iframe>
好的,我已经设法找到了一个解决方案与当前稳定版本(@1.0.7)工作。
当前处理此问题的方法将涉及到与$route相关的事件,动态解析与angular不兼容的url,并通过一个额外的服务处理它们,其工作方式与$http拦截类似。
您可以在这里看到工作代码示例:http://embed.plnkr.co/fIA2xj/preview
主要步骤- 像往常一样传递一个与angular不兼容的url。访问site.com/url/http://site.com
- 监听$routeChangeStart事件并提取以
/url/
开头的路径的正确url参数 - 将正确的url参数编码为与angular兼容的形式(在本例中,我使用base64)。不要使用encodeuriccomponent,因为angular会像对待其他url 一样对待它。
- 用您的业务逻辑重定向到另一个路由,例如:site.com/parsed-url/BASE64_GOES_HERE
- 解码控制器中的URL并像往常一样使用:)
像往常一样创建angular app模块
angular.module('routes',[]).config([
'$routeProvider',
function($routeProvider){
$routeProvider
.when('/test', {templateUrl: 'test.html'})
// This one is important:
// We define a route that will be used internally and handle
// parameters with urls parsed by us via the URLInterceptor service
.when('/parsed-url/:url', {templateUrl: 'url.html', controller:'URLCtrl'})
.when('/', {redirectTo: '/test'})
.otherwise({templateUrl: '404.html'});
}
])
URL拦截器服务(singleton)
.service('URLInterceptor', function($rootScope, $location){
// We listen to $routeChangeStart event and intercept it if
// the path matches our url scheme. In this case, every route
// beginning with /url/ will be caught
$rootScope.$on('$routeChangeStart', function(e, next, current){
// $location.path does change BEFORE actual routing happens,
// so in this case we get parsed new location object
// for free.
// To be hones, a better way of handling this case might be using
// $locationChangeStart event instead, but it would require us to parse urls
// manually.
var path = $location.path();
// check if string begins with '/url/'
var matcher = path.slice(0,5);
var cleanPath = '';
if (matcher === '/url/'){
// Yes it does, yay!
// Remove leading '/url/' to extract the actual parameter
cleanPath = path.slice(5);
// Encode our url to a safe version. We know that encodeURIComponent won't
// work either, so a good choice might be base64.
// I'm using https://code.google.com/p/javascriptbase64/downloads
$location.path('/parsed-url/' + Base64.encode(cleanPath));
// Prevent default event execution. Note that, it won't cancel related $location Events
e.preventDefault();
}
});
return {
decode: Base64.decode,
encode: Base64.encode
}
})
<<h3>控制器/h3>// Main application controller
// We instantiate our URLInterceptor service here
.controller('AppCtrl',function($scope, $location, URLInterceptor){
$scope.navigateTo = function (path) {
$location.path('/url/' + path);
}
})
.controller('URLCtrl', function($scope, $routeParams, URLInterceptor){
$scope.url = URLInterceptor.decode($routeParams.url);
});
你应该记住两件事:
- 虽然我试图创建一个尽可能干净的解决方案,通常以这种方式传递数据到angular不被认为是一个好的做法,所以尽量不要使用它,除非你真的需要。
- 你可以只用一条路由来处理这个问题。我只是觉得这样更干净。
angular.module('routes',[]).config([
'$routeProvider',
function($routeProvider){
$routeProvider
.when('/test', {templateUrl: 'test.html'})
// This one is important:
// We define a route that will be used internally and handle
// parameters with urls parsed by us via the URLInterceptor service
.when('/parsed-url/:url', {templateUrl: 'url.html', controller:'URLCtrl'})
.when('/', {redirectTo: '/test'})
.otherwise({templateUrl: '404.html'});
}
])
.service('URLInterceptor', function($rootScope, $location){
// We listen to $routeChangeStart event and intercept it if
// the path matches our url scheme. In this case, every route
// beginning with /url/ will be caught
$rootScope.$on('$routeChangeStart', function(e, next, current){
// $location.path does change BEFORE actual routing happens,
// so in this case we get parsed new location object
// for free.
// To be hones, a better way of handling this case might be using
// $locationChangeStart event instead, but it would require us to parse urls
// manually.
var path = $location.path();
// check if string begins with '/url/'
var matcher = path.slice(0,5);
var cleanPath = '';
if (matcher === '/url/'){
// Yes it does, yay!
// Remove leading '/url/' to extract the actual parameter
cleanPath = path.slice(5);
// Encode our url to a safe version. We know that encodeURIComponent won't
// work either, so a good choice might be base64.
// I'm using https://code.google.com/p/javascriptbase64/downloads
$location.path('/parsed-url/' + Base64.encode(cleanPath));
// Prevent default event execution. Note that, it won't cancel related $location Events
e.preventDefault();
}
});
return {
decode: Base64.decode,
encode: Base64.encode
}
})
// Main application controller
// We instantiate our URLInterceptor service here
.controller('AppCtrl',function($scope, $location, URLInterceptor){
$scope.navigateTo = function (path) {
$location.path('/url/' + path);
}
})
.controller('URLCtrl', function($scope, $routeParams, URLInterceptor){
$scope.url = URLInterceptor.decode($routeParams.url);
});
我有一个解决方案,但我不知道它是否会帮助你。从Angular文档http://docs.angularjs.org/api/ng.$location $location有一个函数search(search, paramValue)
传递参数:
parameter = encodeURIComponent url
$location.search({ yourURLParameter: parameter }).path('/preview')
读取参数:
url = decodeURIComponent $location.search().yourURLParameter
当然你需要注入$location dependency
我将搜索参数与路由混合。你的搜索需要在你的路线之前。特别是对于旧的浏览器。如果不是url/?search/#/hash
,我认为ie7会爆炸
试试这个格式:
domain.com/?my=params&another=param/#/my/hashes
- 如何使用url加载程序在webpack中导入多个图像
- 使用php或javascript从facebook相册URL中删除多余的部分
- Angular JS IE9 Hashbang url rewriting
- JavaScript下拉菜单-点击按钮并根据所选值重定向到url
- 直接下载文件,而不是从window.open(url)
- 动态地改变“”的URL;添加新项目”;链接使用javascript/jquery
- 通过js在新选项卡中有条件地打开url
- CKFinder 3为所选文件返回错误的URL
- 如何获取不属于我项目的上一页的URL
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 在URL中传递JS对象
- 将纯文本URL转换为可单击链接
- Javascript html每点击一次就会更改url
- 以角度管理动态URL
- Mathias URL shortener
- 如何有效地将游戏数据存储在URL查询字符串中
- 使用带括号的图像URL作为jQuery的背景
- JS:检查URL中的参数,然后迭代一个参数为var的函数
- 传递包含'%的参数'在URL中
- 在AngularJS应用中,把URL传递给$routeParam