[英]How to decorate current state resolve function in UI-Router? Current function isn't invoked
I'm trying to DRY in $stateProvider
and prevent adding the same auth
function in each resolve. 我试图在
$stateProvider
干,并阻止在每个解析中添加相同的auth
函数。 I've created decorator that in each state change would add this function to current state, but auth
function isn't invoked, How to fix it or how to workaround discussed issue? 我已经创建了装饰器,在每个状态更改都会将此函数添加到当前状态,但是不调用
auth
函数,如何修复它或如何解决已讨论的问题?
app.config(function ($stateProvider, $urlRouterProvider, $provide) {
$provide.decorator('$state', function($delegate, $rootScope) {
$rootScope.$on('$stateChangeStart', function(event, state, params) {
if ($delegate.current === "login" || $delegate.current === "register") {
return;
}
console.log("decorator", $delegate);
$delegate.current.resolve = {
auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
//how to invoke this function?
if (AuthService.isAuthenticated()) {
return AuthService.me(); //promise
} else {
return false;
}
}]
};
});
return $delegate;
});
states definition: 州定义:
$stateProvider.state('root', {
abstract: true,
url: '/',
views: {
"": {
controller: 'RootCtrl',
templateUrl: 'views/root.html'
},
"header@root": {
templateUrl: 'views/header.html'
}
}
})
.state('root.home', {
url: urlPrefix,
views: {
"content@artworks": {
templateUrl: 'views/home.html',
//resolve: {
// auth: ['AuthService', '$stateParams', function(AuthService, $stateParams) {
// }]
//}
}
}
})
...
If I understand your requirement correctly, we can use native UI-Router
built-in decorator
: 如果我正确理解您的要求,我们可以使用本机
UI-Router
内置decorator
:
decorator(name, func)
Allows you to extend (carefully) or override (at your own peril) the stateBuilder object used internally by $stateProvider.
允许您扩展(小心)或覆盖(由您自己承担)$ stateProvider内部使用的stateBuilder对象。 This can be used to add custom functionality to ui-router, for example inferring templateUrl based on the state name... (read more in the doc )
这可用于向ui-router添加自定义功能,例如根据州名称推断templateUrl ... ( 在doc中阅读更多内容 )
There is a working plunker 有一个工作的plunker
So, we can have this var auth
所以,我们可以有这个
var auth
var auth = ['AuthService', '$stateParams',
function(AuthService, $stateParams) {
//how to invoke this function on needed states?
if (AuthService.isAuthenticated()) {
return AuthService.me();
} else {
return false;
}
}
];
And here we just use decorator with some "IF" logic 在这里我们只使用装饰器和一些“IF”逻辑
.config(['$stateProvider',
function($stateProvider) {
$stateProvider.decorator('views', function(state, parent) {
var result = {},
views = parent(state);
// some naive example when to not inject resolve
if (state.name === "home") {
return views;
}
// child already has that in parent
if (state.name.indexOf(".") > 0) {
return views;
}
angular.forEach(views, function(config, name) {
// here inject the resolve (if not existing)
config.resolve = config.resolve || {};
// and extend it with the auth stuff above
config.resolve.auth = auth;
result[name] = config;
});
return result;
});
}
])
And later few our states, which will be extended by the above stuff 后来很少有我们的州,这将由上述东西扩展
$stateProvider
.state('home', {
url: "/home",
templateUrl: 'tpl.html',
})
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
controller: 'SharedCtrl',
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'SharedCtrl',
});
I realized that $delegate.current
object contains only raw stateProvider config data. 我意识到
$delegate.current
对象只包含原始的stateProvider配置数据。 To wrap resolve function I add my function to $delegate.$current
on each state change. 要包装解析函数,我将我的函数添加到
$delegate.$current
对每个状态的更改。
$provide.decorator('$state', function($delegate, $rootScope) {
$rootScope.$on('$stateChangeStart', function(event, state, params) {
if ($delegate.current === "err404" || $delegate.current === "login" || $delegate.current === "register") {
return;
}
console.log("decorator", $delegate);
$delegate.$current.resolve["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
if (AuthService.isAuthenticated()) {
console.log('AuthService.me()');
return AuthService.me();
} else {
return false;
}
}]
});
return $delegate;
});
Update 更新
I found related discussion on github , you can add universal resolve function into toState
param: 我在github上找到了相关的讨论,你可以在
toState
param中添加通用解析函数:
app.run(['$rootScope', '$state',
function($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(event, toState) {
if (toState.name === "login" || toState.name === "register") {
return;
}
toState["resolve"]["auth"] = ['AuthService', '$stateParams', function(AuthService, $stateParams) {
if (AuthService.isAuthenticated()) {
return AuthService.me();
} else {
return false;
}
}];
});
}
]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.