Подтвердить что ты не робот

Служба Force AngularJS возвращает данные перед загрузкой контроллера

У меня есть служба в Angular, которая использует мой API для получения информации о пользователе и предоставляет ее моим контроллерам. Он настраивается следующим образом:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
  .service('userInfo', function($http, $cookies){
    $http.get('/api/users/' + $cookies.id).
    success(function(data) {
      var userInfo = data.user[0];

      return userInfo;
    });
  }). // other stuff comes after this

В моих контроллерах я включаю его как:

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    $scope.user = userInfo;
    console.log('user info is')
    console.log(userInfo);

Это не возвращает никаких данных, а если я поместил одну и ту же служебную функцию в сам контроллер, она вернется просто отлично. Что мне здесь не хватает? Никогда не использовались DI/Services в Angular, прежде чем это может быть простой ошибкой где-то.

Мне нужно убедиться, что служба возвращает данные до, которые загружаются контроллером. Как это можно сделать?

4b9b3361

Ответ 1

Вы можете сделать factory, чтобы вернуть такое обещание:

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'ngResource', 'infinite-scroll', 'ui.bootstrap', 'ngCookies', 'seo'])
    .service('userInfo', function ($http, $cookies) {
    var promise = $http.get('/api/users/' + $cookies.id).
    success(function (data) {
        var userInfo = data.user[0];
        return userInfo;
    });
    return promise;
}) // other stuff comes after this

И в вашем контроллере сделайте

function userProfile($scope, $cookies, userInfo, $http, $resource, $routeParams, $rootScope){
    userInfo.then(function(data){
        $scope.user = data;
    });
}

Это может гарантировать, что всякий раз, когда вы используете услугу, она всегда дает вам данные синхронно, вам не обязательно обязательно загружать данные перед загрузкой контроллера.

Ответ 2

Служба userInfo должна вернуть обещание, возвращенное $http. Это обещание будет затем введено в ваш контроллер, и представление будет обновляться, как только обещание будет успешно устранено.


Если вы не хотите, чтобы представление отображалось вообще до того, как userInfo разрешилось, вы должны установить свойство resolve на свой маршрут и ввести там свою службу:

$routeProvider.when('/profile', {
    templateUrl: 'profile',
    controller: userProfile,
    resolve: {
         userInfoData: function ($q, userInfo) {
             return userInfo;
         }
    }
});

Затем просто введите userInfoData в свой контроллер вместо службы userInfo.

Ответ 3

Вы можете назначить объект ресурса своей переменной return $http.get(url)

Ответ 4

Я столкнулся с той же проблемой, в которой мне приходилось загружать данные в службу с использованием ресурса $resource и получать эти данные в области контроллеров $. Я не хотел напрямую возвращать обещание, а затем использовать резольвер в контроллере (как писал @zsong), но сделать все волшебство в службе один раз и использовать возможность назначить обещание непосредственно в $scope как @Joseph Сильбер указывает, вот что я сделал:

return function($scope){promise.then(function(data){$scope.user = data})};

И использовал его в контроллере следующим образом:

userInfo($scope);

Не так много улучшений, но это позволило мне более ясный синтаксис в моих контроллерах, надеюсь, что это поможет даже через три года!