使用UI路由器,有一种方法我只允许动态网址。
例如,我有一个服务MyData
,其get
方法使用$http
。它返回一个条目列表。我想要做的是构造一个有效的入口ID数组,$ state url可以使用它来只允许那些。
var validArray = MyData.get().then(function(res) {
var arr = _.chain(res).pluck('id').flatten().value();
console.log(arr);
// returns [12, 15, 20, 26];
});
我想要实现的只是允许通过$state
网址访问这些数组项。
$stateProvider
.state('entry', {
abstract: true,
url: '/entry/{id:int}', // is there a way to only allow those values from validArray?
resolve: { //etc }
})
.state('entry.detail', {
url: '/detail',
// etc...
});
答案 0 :(得分:0)
我没有使用它,但可以在https://www.dropbox.com/developers/reference/oauthguide的ui-router api文档中找到与您需要的内容非常相似的内容。
它基本上允许您创建自定义路由参数约束,以便您的url: '/entry/{id:validIds}
条目看起来像:
var list = [12, 15, 20, 26];
$urlMatcherFactoryProvider.type('validIds', {
encode: function(item) {
// Represent the list item in the URL using its corresponding index
return list.indexOf(item);
},
decode: function(item) {
// Look up the list item by index
return list[parseInt(item, 10)];
},
is: function(item) {
// Ensure the item is valid by checking to see that it appears
// in the list
return list.indexOf(item) > -1;
}
});
然后定义自定义网址匹配器
angular.config
这需要位于SELECT t1.Col1, t1.Col2
FROM t t1
JOIN t t2 ON t1.Col1 = t2.Col1 and t1.Col2 >= t2.Col2
Group by t1.Col1, t1.Col2
ORDER BY Count(t2.Col2), t1.Col1;
部分,因此您必须完成如何获取有效ID。
(注意,上面的代码是从链接文档中修改的,因此可能无法100%工作)
答案 1 :(得分:0)
在这种情况下,我会使用一个事件来检查id是否有效。这样我们就不仅可以使用$http
( .run()
阶段),但如果ID错误,我们可以更准确地决定该怎么做。所以我们有这些链接:
<a ui-sref="entry({id:1})">
<a ui-sref="entry({id:22})">
<a ui-sref="entry({id:333})">
<a ui-sref="entry({id:4444})">
这可能是我们带有支持ID的data.json:
{
"allowedIds": [
22, 333
]
}
通过此服务,我们可以检查是否允许id。它也会返回promise,以防$ http用于从服务器加载数据:
.factory('IdValidator', ['$http',
function($http) {
var allowedIds = null;
// return bool or promise
var validate = function(id){
if(allowedIds){
return isValid(id);
}
return $http
.get("data.json")
.then(function(resp){
allowedIds = resp.data.allowedIds;
return isValid(id);
})
}
// compare id with loaded allowed ids
var isValid = function(id){
return allowedIds.indexOf(id) >= 0;
}
return {
validate : validate
}
}]);
最后,我们需要对状态变化做出一些决定:
.run(['$rootScope', '$state', 'IdValidator',
function($rootScope, $state, IdValidator) {
$rootScope.$on('$stateChangeStart', function(event, to, params) {
if (to.name !== "entry"){
return;
}
var result = IdValidator.validate(params.id) ;
// allowedIds loaded, we now that this id is OK
if(result === true){
return;
}
// now we have to stop exectuion any how
event.preventDefault();
// result is false - id is not allowed
if(result === false){
$state.go("home");
return;
}
// wait for a promise and try this state again
result.then(function(isValid){
$state.go(to.name, params);
})
});
}])
应该很清楚。如果结果是true
或false
,我们可以采取行动..如果结果是承诺,我们只是等待其解决方案..然后再次重定向到此状态
通过这种方式,我们可以在整个应用程序生命周期内允许ID ...
检查here