Angularjs 第二次未调用Resolve
我有一些路线定义如下:Angularjs 第二次未调用Resolve,angularjs,angular-ui-router,ionic,Angularjs,Angular Ui Router,Ionic,我有一些路线定义如下: $stateProvider .state('app', { url: '/', abstract: true, views: { 'menuContent': { templateUrl: 'templates/home.html'
$stateProvider
.state('app', {
url: '/',
abstract: true,
views: {
'menuContent': {
templateUrl: 'templates/home.html'
}
}
})
.state('app.restricted', {
url: '/restricted',
views: {
'content': {
templateUrl: 'templates/restricted/restricted-dashboard.html',
controller: 'RestrictedController as vmRestricted'
}
},
resolve: {
isGranted: 'isGranted'
}
})
.state('app.restricted.pending', {
url: '/pending',
views: {
'tabsView': {
templateUrl: 'templates/restricted/restricted-manage-pending.html',
controller: 'RestrictedPendingController as vm'
}
},
resolve: {
isGranted: 'isGranted'
}
})
.state('app.restricted.devices', {
url: '/devices',
views: {
'tabsView': {
templateUrl: 'templates/trusted/restricted-manage-devices.html',
controller: 'RestrictedDevicesController as vm'
}
},
resolve: {
isGranted: 'isGranted'
}
})
.state('app.grant', {
url: '/grant-access',
views: {
'content': {
templateUrl: 'templates/grant-access.html',
controller: 'GrantAccessController as vm'
}
}
})
;
在这些路线中,我有一个限制区和一个授权访问页面来授权访问限制区。
当isgrant
解析提供程序被拒绝时,我重定向到app.grant
路由
这是执行此操作的代码:
$rootScope.$on(AngularEvents.STATE_CHANGE_ERROR, _onStateChangeError);
function _onStateChangeError(event, toState, toParams, fromState, fromParams, error){
switch (error) {
case 'accessRejected':
$state.go('app.grant');
break;
}
}
以下是我的isgrated
提供商的代码:
(function() {
'use strict';
angular.module('app')
.provider('isGranted', isGrantedProvider);
isGrantedProvider.$inject = [];
function isGrantedProvider() {
this.$get = isGranted;
isGranted.$inject = ['$q', '$log', 'grantService'];
function isGranted($q, $log, grantService){
$log.log('isGrantedProvider');
if (grantService.isGranted()) {
return $q.when(true);
} else {
return $q.reject('accessRejected');
}
}
}
})();
(grantService.isgrant()
只返回一个布尔值)
第一次使用$state.go('app.restricted')
进入app.restricted
路径时,将执行提供程序。
该路由被拒绝,因为未授予访问权限,我们被重定向到app.grant
路由
在此页面中,用户可以登录并访问限制区域。用户登录后,我们将其重定向到app.restricted.pending
路由,但未调用解析,路由被拒绝,我们再次重定向到app.grant
路由,而访问被授予
为什么不叫决心?
有办法强迫它吗
编辑
经过一些测试,我有了新的信息
我看到resolve只有在作为服务时才被第二次调用:
当我们进入以下状态时,始终执行此解析:
state('app.restricted', {
url: '/restricted',
views: {
'content': {
templateUrl: 'templates/restricted/restricted-dashboard.html',
controller: 'RestrictedController as vmRestricted'
}
},
resolve: {
isGranted: ['$log', function($log) {
$log.log('RESOLVE');
}]
}
})
state('app.restricted', {
url: '/restricted',
views: {
'content': {
templateUrl: 'templates/restricted/restricted-dashboard.html',
controller: 'RestrictedController as vmRestricted'
}
},
resolve: {
isGranted: 'isGranted'
}
})
angular.module('app')
.provider('isGranted', isGrantedP);
isGrantedP.$inject = [];
function isGrantedP() {
this.$get = isGranted;
isGranted.$inject = ['$q', '$log'];
function isGranted($q, $log){
$log.log('RESOLVE');
}
}
但是,即使我再次进入状态,此解析也只执行一次:
state('app.restricted', {
url: '/restricted',
views: {
'content': {
templateUrl: 'templates/restricted/restricted-dashboard.html',
controller: 'RestrictedController as vmRestricted'
}
},
resolve: {
isGranted: ['$log', function($log) {
$log.log('RESOLVE');
}]
}
})
state('app.restricted', {
url: '/restricted',
views: {
'content': {
templateUrl: 'templates/restricted/restricted-dashboard.html',
controller: 'RestrictedController as vmRestricted'
}
},
resolve: {
isGranted: 'isGranted'
}
})
angular.module('app')
.provider('isGranted', isGrantedP);
isGrantedP.$inject = [];
function isGrantedP() {
this.$get = isGranted;
isGranted.$inject = ['$q', '$log'];
function isGranted($q, $log){
$log.log('RESOLVE');
}
}
为什么不每次都调用此服务?是因为服务是单体的吗?我应该如何继续?经过大量的调查和测试,我找到了解决方案 首先,让我们看看它为什么不起作用 正如文档(.$stateProvider)中提到的,如果解析是一个字符串,那么它对应于一个服务 工厂-{string | function}:如果是string,则它是服务的别名。 否则,如果是函数,则注入该函数并返回它所处理的值 附属国。若结果是一个承诺,那个么在确定其价值之前就已经解决了 注入控制器 正如angularjs文档()中提到的,所有服务都是单例的,这意味着它将只实例化一次 注:Angular中的所有服务均为单例服务。这意味着 injector最多使用每个配方一次来创建对象。这个 然后,injector缓存参考,以备将来需要 为什么它很重要? 因为解析不会在我们的服务中调用函数。它们只使用实例化服务的返回值但是因为我们的服务只实例化一次,所以返回值总是相同的!(因为我们的服务初始化只调用一次) 我们能做什么? 从我的测试中,我可以看到如下定义的解决方案:
resolve: {
myResolve: ['$log', function($log) {
$log.log('My Resolve!');
}]
}
resolve: {
myResolve: ['myResolveService', function(MyResolveService) {
myResolveService.log();
}]
}
angular.module('app')
.factory('myResolve', myResolve);
myResolve.$inject = ['$log'];
function myResolve($log) {
function service(){
this.log = log;
function log() {
$log.log('My resolve!');
}
}
return new service();
}
始终执行,因此我们可以通过这种方式编写它们以使其正确工作
但是如果我想使用我的服务,我该怎么办?
我发现,能够使用我的服务并具有类似于以下语法的最佳工作解决方案:myResolve:“myResolveService”
是这样声明我的解析:
resolve: {
myResolve: ['$log', function($log) {
$log.log('My Resolve!');
}]
}
resolve: {
myResolve: ['myResolveService', function(MyResolveService) {
myResolveService.log();
}]
}
angular.module('app')
.factory('myResolve', myResolve);
myResolve.$inject = ['$log'];
function myResolve($log) {
function service(){
this.log = log;
function log() {
$log.log('My resolve!');
}
}
return new service();
}
我的服务是这样的:
resolve: {
myResolve: ['$log', function($log) {
$log.log('My Resolve!');
}]
}
resolve: {
myResolve: ['myResolveService', function(MyResolveService) {
myResolveService.log();
}]
}
angular.module('app')
.factory('myResolve', myResolve);
myResolve.$inject = ['$log'];
function myResolve($log) {
function service(){
this.log = log;
function log() {
$log.log('My resolve!');
}
}
return new service();
}
此代码也可适用于返回承诺的解析:
决心:
resolve: {
myResolve: ['myResolveService', function(MyResolveService) {
return myResolveService.check();
}]
}
服务:
angular.module('app')
.factory('myResolve', myResolve);
myResolve.$inject = ['$q', 'myService'];
function myResolve($q, myService) {
function service(){
this.check = check;
function check() {
var defer = $q.defer();
if (myService.check()) {
defer.resolve(true);
} else {
defer.reject('rejected');
}
return defer.promise;
}
}
return new service();
}
确定没有调用解析还是grantService返回了错误的值?@AurélienThieriot我确定没有调用解析,因为提供程序中的$log没有显示出来。不错!