AngularJS Route Resolve

Um recurso muito interessante das rotas que não vejo muita gente usando é o resolve. Com ele é possível injetar algumas informações direto no controller.

Para ilustrar esse exemplo vamos simular uma operação de editar um usuário.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app.config(function($routeProvider){
$routeProvider
.when('/Editar/:id', {
controller: 'UserCtrl',
templateUrl: 'MyApp.html'
})
//...
});
app.controller("UserCtrl", function ($location, $routeParams, UserService) {
var data = this;
UserService.getUser($routeParams.id)
.success(function (response) { data.User = response; })
.error(function (error) { $location.path('UserNotFound'); });
//...
});

No exemplo acima o controller faz a busca do usuário através do metodo UserService.getUser que faz uma requisição Ajax através do $http.get.

Se o usuário foi encontrado (success), preenchemos o scopo User com o response.

Se o usuário não foi encontrado (error), redirecionamos o usuário para outra rota através do $location.path

Não seria mais interessante a rota verificar se existe o usuário e já injetar o User no controller?

Vamos ver como isso funciona na prática.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.config(function($routeProvider){
$routeProvider
.when('/Editar/:id', {
controller: 'UserCtrl',
templateUrl: 'MyApp.html',
resolve: {
user: function($q, $location, $routeParams, UserService) {
var deferred = $q.defer();
UserService.getUser($routeParams.id)
.success(function (response) { deferred.resolve(response); })
.error(function (error) { $location.path('UserNotFound'); });
return deferred.promise;
}
}
})
//...
});
app.controller("UserCtrl", function (user) {
var data = this;
data.User = user;
//...
});

No exemplo acima movemos toda a lógica para dentro da rota, aonde foi criado o objeto resolve que vai ser injetado no controller.

Também foi usado o serviço $q porque estamos fazendo uma requisição HTTP e devemos esperar que ela seja executada antes de chamar o controller.

Finalmente modificamos o controller que agora recebe o user como parâmetro.

Se você tem dúvidas sobre o funcionamento das promisses, serviço $q… recomendo a leitura do artigo AngularJS Promises - O guia definitivo

Você também pode usar o resolve para injetar dados iniciais para o controller.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app.config(function($routeProvider){
$routeProvider
.when('/Listar', {
controller: 'ListCtrl',
templateUrl: 'MyApp.html',
resolve: {
init: function() {
return {
paginacao: { itensPorPagina: 10, ordenarPor: 'Nome' },
codigos: [2,5,9]
};
}
}
})
//...
});
app.controller("ListCtrl", function ($log, init) {
$log.info(init.paginacao.itensPorPagina);
$log.info(init.paginacao.ordenarPor);
$log.info(init.codigos);
//...
});

Até os próximos artigos!