Первоначально в своем приложении я создал контроллеры с очень простыми вызовами $http для получения ресурса путем получения идентификатора объекта из URL-адреса ($routeParams). Ng-repeat правильно отображает результаты.
Однако я заметил, что обновление в более позднем представлении (другой контроллер) уничтожило данные и сломало страницу. Итак, я создал функцию в службе, которая будет использоваться в нескольких контроллерах, чтобы проверить, доступны ли данные, и отреагировать следующим образом:
1) Если ресурс определен, верните его (без вызова API) 2) Если ресурс не определен, получите идентификатор из URL-адреса и получите его из API 3) Если ресурс не определен и вы не можете получить идентификатор, просто верните false.
Однако это сломало код: шаблон, отрендеренный до того, как служба вернула данные, а ng-repeat не обновился. Код выглядит следующим образом:
angular.module('myApp', ['ngCookies'])
.config(...)
.service('myService', ['$cookies', '$http', function($cookies, $http) {
myData = {};
return {
getData:function(dataID) {
if(myData.name) {return myData);
else if (dataID && dataID !== '') {
$http.get('/api/data/' + dataID)
.success(function(data) {
myData = data.object;
$cookies.dataID = data.object.id;
return myData;
}
}
else { return false; }
}
}
}]);
function myCtrl($scope, $http, $routeParams, myService) {
$scope.data = myService.getData($routeParams.dataID);
...
}
И вот шаблон. Это в нефрите, что означает, что вместо угловых скобок вы просто перечисляете элемент с параметрами в скобках сразу после него и содержимым после скобок.
h2 My heading
ul
li(ng-repeat='option in data')
a(href="#", ng-click='someFuncInCtrl(option.name)') {{ option.name }}
Когда контроллер сделал сам $http.get, ng-repeat работал нормально, потому что $scope был обновлен в обратном вызове «.success». Теперь, когда есть служба, которая возвращает данные после небольшой задержки, «$scope.data» просто не определено, список ng-repeat пуст.
Я использовал console.log для проверки myData прямо перед возвратом «return myData», и myData работает, просто не возвращается вовремя, и по какой-то причине список не обновляется всякий раз, когда $scope получает данные.
Я посмотрел, используя разрешение $routeProvider... но это усложняет получение идентификатора из URL-адреса, поскольку объект разрешения, похоже, не имеет доступа к $routeParams. Я знаю, что $scope.$apply должен помочь обновить область действия, когда она изменяется внешними функциями... но я понятия не имею, куда ее поместить. наиболее похожая проблема на SO не использовала службу.
Я попытался:
$scope.$apply($scope.data = myService.getData($routeParams.dataID));
И
$scope.$apply(function() {
$scope.data = myService($routeParams.dataID);
});
Оба раза я получил только ошибку: $digest уже выполняется.