Обещания Angular JS $http ведут себя как настоящие обещания $q?

Я знаю, что Angular может обрабатывать промисы внутри контроллеров. Например:

function MyCtrl($scope) {
  $scope.myvar = getDeferredPromise();
}

Основной цикл дайджеста angular обрабатывает это изящно, присваивая любое значение, которое отложенная функция наконец возвращает позже, myvar.

Однако, хотя метод $http.get() возвращает обещание, я не могу заставить его работать таким образом. Например:

function MyCtrl($scope, $http) {
  $scope.myvar = $http.get('/url');
} 

«Обещание», возвращаемое методом get, имеет метод success, который принимает функцию, которой присваиваются данные, которые можно было бы присвоить myvar. .

Однако у него также есть метод then, но ему передается весь объект ответа, а не только часть данных! Это то, что, кажется, в конечном итоге назначается myvar!

Эта скрипка может помочь: http://jsfiddle.net/QKnNC/1/

Я делаю что-то не так здесь? Или это как-то "по дизайну"?


person Rik    schedule 06.09.2013    source источник
comment
Я предполагаю, что это задумано: промисы обычно выполняются только с одним значением, поэтому вам нужно будет передать весь объект ответа, чтобы сделать его доступным.   -  person Bergi    schedule 06.09.2013


Ответы (3)


http://docs.angularjs.org/api/ng.%24http

Служба $http — это функция, которая принимает один аргумент — объект конфигурации — который используется для генерации HTTP-запроса и возвращает обещание с двумя специфическими для $http методами: успех и ошибка.

$http возвращает обещание, поэтому вам нужно связать then, чтобы получить данные.

IPService.getV1().then(function (response) {
    console.log(response)
    $scope.value1 = response.data;
});
person zs2020    schedule 06.09.2013
comment
@Рик. Да. Если вы используете $resource, он возвращает завернутое обещание, которое можно применить к области видимости напрямую. - person zs2020; 06.09.2013
comment
Во-первых, ваш пример выше функционально похож на мой метод getV2. Кроме того, не разумно ли хранить это внутри службы, а не выставлять контроллеру весь объект ответа? - person Rik; 06.09.2013
comment
Р.э. $resource: это очень интересно! Не сталкивался с этим сервисом! Пойду и поиграю! Большое спасибо. - person Rik; 06.09.2013

then — это общая функция обещания, которая принимает обратный вызов об успехе и ошибке, и вы получаете разрешенное значение, каким бы оно ни было. success и error специфичны для $http и являются псевдонимами для then с одним исключением: они устанавливают набор полезных аргументов, а не только данные. См. источник.

person Steve Klösters    schedule 06.09.2013

Это по дизайну. Ваш метод getV2() — это то, что вам нужно. Поскольку вы используете GET, вы можете сохранить результат своего обещания и вернуть его при последующих вызовах getV2():

var v2promise, v2data;
return {
   getV2: function() {
      if(!v2promise) {
        v2promise = $http.get('http://ip.jsontest.com/').then(
          function(response) {
             v2data = response.data;
             return v2data;
        });
      }
      return v2promise;
   }
}
person Mark Rajcok    schedule 06.09.2013