Nano Hash - криптовалюты, майнинг, программирование

AngularJS ng-repeat с данными из службы

Первоначально в своем приложении я создал контроллеры с очень простыми вызовами $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 уже выполняется.


  • возможно, вы захотите попробовать подход restful service в учебнике на сайте документации angular. Возвращает обещание. docs.angularjs.org/tutorial/step_11 19.02.2013

Ответы:


1

Проблема в том, как вы взаимодействуете с сервисом. Поскольку ваша функция getData может возвращать как синхронную, так и/или асинхронную информацию, вы не можете просто использовать обычные return.

$http.get('/api/data/' + dataID)
    .success(function(data) {
        myData = data.object;
        $cookies.dataID = data.object.id;
        return myData;
    });

return в приведенном выше фрагменте ничего не вернет из getData, потому что он будет выполнен в контексте обратного вызова $http.get (а не в стеке вызовов getData).

Наилучший подход к обработке запросов на синхронизацию и асинхронные сервисы — использовать обещания.

Ваша функция getData должна выглядеть примерно так:

getData:function(dataID) {
    var deferred = $q.defer();
    if(myData.name) {
       deferred.resolve(myData);
    } else if (dataID && dataID !== '') {
        $http.get('/api/data/' + dataID)
            .success(function(data) {
                 myData = data.object;
                 $cookies.dataID = data.object.id;
                 deferred.resolve(myData);
                 // update angular's scopes
                 $rootScope.$$phase || $rootScope.$apply();
             });
    } else { 
       deferred.reject();
    }

    return deferred.promise;
}

Примечание. Вам необходимо внедрить $rootScope в свой сервис.

И на вашем контроллере:

function myCtrl($scope, $http, $routeParams, myService) {
    myService.getData($routeParams.dataID).then(function(data) {
        // request was successful
        $scope.data = data;        
    }, function() {
        // request failed (same as your 'return false')
        $scope.data = undefined;
    });
}
19.02.2013
  • Благодаря тонну. Также внедрил $q в службу. Работал как шарм. 19.02.2013
  • Спасибо Спасибо! Мне нужно было внедрить $rootScope в мою службу, чтобы обновить области видимости angular после разрешения моего отложенного (через $rootScope.$$phase || $rootScope.$apply()) 31.07.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..