My situation is that: I write a web-app like gmail: normal messages, starred messages, label messages sections (3 states). They have same functions except different webservice calling. But format of their result are same:
{
"result": [],
"count": 5
}
I want to use only controller for 3 states. So I use resolve
to achieve that.
- Solution 1:
// route.js
/*
Message.listMessages() and Message.listStarredMessages() are custom `actions` of $resource. Message is factory
*/
$stateProvider
.state('dashboard.messages', {
// ...
controller: 'SharedMessagesController',
controllerAs: 'vm',
resolve: {
obj: function (Message, $stateParams) {
return Message.listMessages({
page: $stateParams.page
});
}
})
.state('dashboard.starred-messages', {
// ...
controller: 'SharedMessagesController',
controllerAs: 'vm',
resolve: {
obj: function (Message, $stateParams) {
return Message.listStarredMessages({
page: $stateParams.page
});
}
});
// shared-messages.controller.js
angular
.module('app.message')
.controller('SharedMessagesController', SharedMessagesController);
SharedMessagesController.$inject = ['obj'];
/* @ngInject */
function SharedMessagesController(obj) {
var vm = this;
vm.messages = obj; // when obj is resolved, messages will have result
}
<!-- messages.html -->
<div ng-repeat="message in vm.messages['result']">
<!-- do something -->
</div>
- Solution 2: Perfect! But I want to using
<div ng-repeat="message in vm.messages">
instead of<div ng-repeat="message in vm.messages['result']">
. I need to changeshared-messages.controller.js
file
// shared-messages.controller.js
/* @ngInject */
function SharedMessagesController(obj) {
var vm = this;
vm.messages = [];
// after server return result, will assign it to `vm.messages`
obj.$promise.then(function(data) {
vm.messages = data['result'];
});
}
- Solution 3: The solution is good. But there is one more way to achieve same result.
// route.js
.state('dashboard.messages', {
// ...
controller: 'SharedMessagesController',
controllerAs: 'vm',
resolve: {
obj: function (Message, $stateParams) {
return Message.listMessages({
page: $stateParams.page
}).$promise; // controller will waiting until server return result (is resolved)
}
})
// shared-messages.controller.js
/* @ngInject */
function SharedMessagesController(obj) {
var vm = this;
vm.messages = obj['result']; // obj now is ready to use, don't need to waiting like 2 above solutions
}
- I like solution 2 because controller doesn't need to waiting, and template works to variable directly instead of that children property of the variable