I have code like this:
meow.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/page', {
templateUrl: 'application/partials/page.html',
controller: 'index',
resolve: {'page': ['$resolve', function($resolve) {return $resolve.page();}]}
})
.when('/page2', {
templateUrl: 'application/partials/page2.html',
controller: 'index',
resolve: {'page2': ['$resolve', function($resolve) {return $resolve.page2();}]}
})
...
.otherwise({
redirectTo: '/error'
});
}]);
meow.factory('$resolve', ['$q', '$user', function($q, $user) {
return {
page: function() {
var deferred = $q.defer();
if ($user.logged()) {
$http.get('/json/page')
.success(function(data, status, headers, config) {
deferred.resolve();
})
.error(function(data, status, headers, config) {
deferred.reject();
});
} else {
deferred.reject();
}
return deferred.promise;
}
page2:...
page3:...
...
}
}]);
As you can see there is check of user access in $resolve
factory: $user.logged()
, but $user
is async and on first load it cause problems with access.
The question is how to make all my resolves wait for $user
?
I have $user.q() function which giving promise, but how to inject it to my code for all resolves? Or maybe some other solution with $routeChangeStart
or $locationChangeStart
events? Or should I just insert $user.q().then(...)
in every resolve?
Update 1:
My user code:
meow.factory('$user', ['$q', '$http', function($q, $http) {
var id = null;
var accesslevel = 0;
function update() {
var deferred = $q.defer();
$http.get('/json/user')
.success(function(data, status, headers, config) {
if (data.logged) {
id = data.id;
accesslevel = data.accesslevel;
} else {
id = null;
accesslevel = 0;
}
deferred.resolve();
})
.error(function(data, status, headers, config) {
deferred.reject();
});
return deferred.promise;
}
var q = update();
return {
logged: function() { return (id) ? true : false; },
id: function() { return id; },
accesslevel: function() { return accesslevel; },
reset: function() {
id = null;
accesslevel = 0;
},
update: function() { return q = update(); },
q: function() { return q; }
};
}]);
Not controller should wait for $user.q()
, resolve should. When I tryed to make it as additional resolve in $routeProvider
, page
resolve trying to load /json/page
, but should not until $user.q()
resolved and $user.logged() = true
.
So the only way is to add
page: function() {
var deferred = $q.defer();
$user.q().then(function() {
if ($user.logged()) {
$http.get('/json/page')
.success(function(data, status, headers, config) {
deferred.resolve();
})
.error(function(data, status, headers, config) {
deferred.reject();
});
} else {
deferred.reject();
}
});
return deferred.promise;
}
to each resolve?
The way you would normally approach dependencies like this would be to make user
its own resolve and then make other resolve(s) depend on it, like so:
resolve: {
user: function($user) {
return $user.q();
},
somethingElse: function(user, $otherService) {
// Whatever else
}
}
This is kind of covered in UI Router wiki .
$user itself could be a promise that resolve to all service methods or you could resolve each service individually.
Usage
$user.then(function(userService) {
userService.logged();
});
Resolution
var userDeferred= $q.defer();
userDeferred.resolve({
logged: function() {
return false;
}
});
return userDeferred.promise;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.