Доброе время суток!
В этом небольшом посте я хочу рассказать про использование Deferred объектов AngularJS.
Механизм Deferred объектов, а точнее идея была добавлена из библиотеки Q Криса Ковала. Суть его заключается в том, что если функция не может вернуть значение или исключение без блокировки, то она возвращает Promice объект, который является наблюдателем за результатом выполнения. Как только результат будет получен, либо в момент получения произойдет ошибка, Deferred объект извещает об этом наблюдателя.
Довольно часто перед загрузкой контроллера необходимо получить данные для его работы. Говоря о получение данных я имею в виду данные, получение которых занимает неопределенное время. Наиболее частый случай — это прием данных от сервера приложения. Для решения этой задачи нам нужно передать параметр resolve в $routeProvider при настройке роутинга приложения. Resolve представляет собой объект указывающий контроллеру на зависимость. Как только все зависимости будут решены, они помещаются в контроллер, после чего происходит дальнейшая инициализации контроллера.
Более наглядно это можно увидеть на примере.
angular.module('phonecat', ['phonecatFilters', 'phonecatServices', 'phonecatDirectives']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: PhoneListCtrl,
resolve: PhoneListCtrl.resolve}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: PhoneDetailCtrl,
resolve: PhoneDetailCtrl.resolve}).
otherwise({redirectTo: '/phones'});
}]);
function PhoneListCtrl($scope, phones) {
$scope.phones = phones;
$scope.orderProp = 'age';
}
PhoneListCtrl.resolve = {
phones: function(Phone, $q) {
var deferred = $q.defer();
//выполняем запрос на получение данных
//если данные успешно приняты выполним deferred.resolve()
//если произошла ошибка выполним deferred.reject()
Phone.query(function(successData) {
deferred.resolve(successData);
}, function(errorData) {
deferred.reject();
});
return deferred.promise;
},
delay: function($q, $defer) {
var delay = $q.defer();
$defer(delay.resolve, 1000);
return delay.promise;
}
}
В выше указанном примере $q.defer() — создает экземпляр объекта Defer. Данный объект имеет два метода, для возврата значения — deferred.resolve(val) и возврата отказа по какой либо причине — deferred.reject(reason). Методы resolve или reject вызываются в callback методах, вызовы которых происходит в случае успешного приема данных или в случае возникновения ошибки.
Как только все Deferred объекты будут выполнены их результаты добавляются в контроллер, после этого происходит событие смены маршрута и мы можем выполнять различные действия с данными внутри контроллера.
Автор: ese