我有这样的状态设置。这基于解决方案中的:pageSlug via pageObj从数据库提供动态页面。 我想知道是否有可能使状态本身的data.access成为动态变量,这意味着状态将从数据库中获取其访问属性。
.state('site.home.page', {
url: ':pageSlug',
data: {
access: AccessLevels.anon //make me dynamic! Can I access the resolve from here?
},
resolve: {
pageObj : function($stateParams, REST, $state) {
return REST.getOne("/page?slug="+$stateParams.pageSlug).then(function(rtnData) {
$state.current.data.access = rtnData.access; //this doesn't work, $state.current doesn't seem to be loaded?
return rtnData;
});
},
},
类似的设置
非常感谢任何帮助。
编辑:原来,$ state在解析或onEnter中无法使用。可注射的$ transition $状态正在整合中。 https://github.com/angular-ui/ui-router/issues/1257
答案 0 :(得分:1)
当$state.current.data.access = rtnData.access;
运行时,$state.current
是您来自的状态,而不是。一切都解决后,$state.current
才会被更改。
您可能希望在那里记录$state.current
以查看它是否是您认为应该是的,而不是来自〜之前的状态(您来自)。与$stateParams
相同。
根据您何时需要访问数据,您可以在$stateChangeSuccess
事件中进行设置。
答案 1 :(得分:1)
首先,我认为服务器应该在访问被拒绝时返回正确的HTTP状态代码,这样您就可以安全地处理它(并防止数据通过不应该看到的线路)。
但假设这不是一个选项,如果我是你,我会创建一个服务来存储你在解析页面时从服务器收到的ACL,如下所示:
(我正在输入这个,所以请考虑更像元代码)
// Service to keep track of ACL's
.factory('aclService', [function(){
var service = {},
acls = {};
service.setAcl = function(slug, acl){
acls[slug] = acl;
};
service.getAcl = function(slug){
return acls[slug] || 'access denied'; // or whatever you want to return by default
};
return service;
}]);
因此您可以在收到ACL时使用它来存储ACL:
.state('site.home.page', {
url: ':pageSlug',
data: {
access: AccessLevels.anon //make me dynamic! Can I access the resolve from here?
},
resolve: {
pageObj : function($stateParams, REST, $state, aclService) {
return REST.getOne("/page?slug="+$stateParams.pageSlug).then(function(rtnData) {
// Store the ACL in the service
aclService.setAcl($stateParams.pageSlug, rtnData.access);
});
}
}
});
然后查阅ACL以决定是否要加载状态:
// Listen to the SUCCESS event
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){
var acl = aclService.getAcl(toParams.pageSlug);
// Do whatever check is needed to verify access
if(toState.data.access !== acl){
// Do whatever you like to do here when access is denied
// The state is already loaded but you can redirect the user away
}
});
由于您正在使用服务来存储ACL的缓存,因此您可以进一步优化并在状态转换之前添加额外的检查,例如:
// Listen to the START event here
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
var acl = aclService.getAcl(toParams.pageSlug);
// Return early if no cache is found
if(acl === undefined){
return;
}
// Do whatever check is needed to verify access
if(toState.data.access !== acl){
// Do whatever you like to do here when access is denied
// The state will no longer be loaded now
}
});
如果你真的想把它发挥到极致,你可以在引导你的AngularJS应用程序时预先加载所有ACL的aclService,这样你就可以开始使用热缓存了。
希望有所帮助!