AngularJS: повтор последних запросов при обрыве соединения
Table of Contents
Решил сделать кнопку «обновить», которая показывается при обрыве сетевого соединения и повторяет неудавшиеся запросы. Очень актуально для мобильных приложений.
Задача состоит из двух частей:
- Запросы к api на уже сформированной странице (сохранение форм и другие действия без смены контроллера и урла)
- Переход на новый урл (смена через маршрутизацию AngularJS)
Первое у меня сделано через расширение $resource (сделано оно изначально было для другого, но и этот функционал туда вписывается хорошо).
Вкратце идея такова: каждый запрос заносится в объект-хранилище; когда запрос успешно выполняется, он из этого хранилища выбрасывается. Если запрос не был выполнен, то его параметры остаются в хранилище, а в $rootScope ставится флаг, говорящий о том, что произошёл сбой при соединении с api. При этом показывается кнопка «повторить последние запросы», при нажатии на которую сохранённые запросы выполняются заново.
А хотел я остановиться на втором пункте, т.к. реализация не требует расширения библиотеки angular, а реализуется штатными средствами, да к тому же и кода немного.
При смене урла AngularJS сначала делает запрос для загрузки шаблона, и если он не отработал, то выполнение логики контроллера не начинается (кстати, именно поэтому в шаблоне обязательно нужен контент, без него контроллер работать не будет).
Если шаблон не загрузился, то будет сгенерировано событие $routeChangeError. Вешаем обработчик на это событие, который ставит переменную в $rootScope. Для повтора загрузки шаблона и дальнейшего выполнения логики контроллера достаточно выполнить $route.reload();. Так что вот весь код:
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
(function () { $rootScope.routeError = false; $rootScope.$on('$routeChangeError', function (event, current, prev, rejection) { $rootScope.routeError = true; }); $rootScope.$on('requests.rerun', function (event, current, prev, rejection) { if ($rootScope.routeError) { $route.reload(); $rootScope.routeError = false; } }); }()); $rootScope.rerunRequests = function rerunRequests() { $rootScope.$emit('requests.rerun'); }; |
index.html
1 2 3 |
<div ng-show="controllerDataLoadError || routeError"> <a href="javascript:;" ng-click="rerunRequests()">Повторить последний запрос</a> </div> |
Единственный минус такого подхода
Если вместо callback-ов используются прямое присваивание значения, то повтор запроса не вернет это значение в нужное место. Выход — не использовать такой синтаксис, тем более, что он менее удобен.
Т.е. не надо вместо
1 2 3 4 5 6 |
MyService.get(params, function (response) { $scope.response = response; $scope.$emit('extendedGeoSelector.show'); LoadRendererService.setLoaded(); }); |
использовать
1 |
$scope.response = MyService.get(params); |
Similar Posts
- None Found
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.