서비스에서 $ http 응답 처리 실제 $http요청을 보낼 수 없으므로

최근에 내가 여기 에서 직면하고있는 문제에 대한 자세한 설명을 게시했습니다 . 실제 $http요청을 보낼 수 없으므로 시간 초과를 사용하여 비동기 동작을 시뮬레이션했습니다. @Gloopy의 도움으로 모델에서보기로 데이터 바인딩이 올바르게 작동합니다.

이제 (로컬에서 테스트 됨) $http대신 사용 $timeout하면 비동기 요청이 성공했으며 data서비스에서 json 응답으로 채워졌습니다. 그러나 내 견해는 업데이트되지 않습니다.

Plunkr 업데이트 여기



답변

원하는 것을 수행하는 Plunk는 다음과 같습니다. http://plnkr.co/edit/TTlbSv?p=preview

아이디어는 약속과 직접 “그런 다음”기능을 사용하여 비동기 적으로 리턴 된 응답을 조작하고 액세스하는 것입니다.

app.factory('myService', function($http) {
  var myService = {
    async: function() {
      // $http returns a promise, which has a then function, which also returns a promise
      var promise = $http.get('test.json').then(function (response) {
        // The then function here is an opportunity to modify the response
        console.log(response);
        // The return value gets picked up by the then in the controller.
        return response.data;
      });
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  // Call the async method and then do stuff with what is returned inside our own then function
  myService.async().then(function(d) {
    $scope.data = d;
  });
});

다음은 요청을 캐시하는 약간 더 복잡한 버전이므로 처음으로 만 만드십시오 ( http://plnkr.co/edit/2yH1F4IMZlMS8QsV9rHv?p=preview ).

app.factory('myService', function($http) {
  var promise;
  var myService = {
    async: function() {
      if ( !promise ) {
        // $http returns a promise, which has a then function, which also returns a promise
        promise = $http.get('test.json').then(function (response) {
          // The then function here is an opportunity to modify the response
          console.log(response);
          // The return value gets picked up by the then in the controller.
          return response.data;
        });
      }
      // Return the promise to the controller
      return promise;
    }
  };
  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = {};
  };
  $scope.getData = function() {
    // Call the async method and then do stuff with what is returned inside our own then function
    myService.async().then(function(d) {
      $scope.data = d;
    });
  };
});

답변

간단하게하자. 그것은 간단합니다

  1. promise서비스 반품 (서비스에서 사용할 필요 없음 then)
  2. then컨트롤러에서 사용

데모. http://plnkr.co/edit/cbdG5p?p=preview

var app = angular.module('plunker', []);

app.factory('myService', function($http) {
  return {
    async: function() {
      return $http.get('test.json');  //1. this returns promise
    }
  };
});

app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function(d) { //2. so you can use .then()
    $scope.data = d;
  });
});

답변

비동기식이므로 $scopeajax 호출이 완료되기 전에 데이터를 가져옵니다.

당신은 사용할 수 있습니다 $q생성 서비스에 promise다시 컨트롤러를주고, 컨트롤러는 내 결과를 얻을 수 then()에 대한 호출 promise.

당신의 봉사에서

app.factory('myService', function($http, $q) {
  var deffered = $q.defer();
  var data = [];
  var myService = {};

  myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
      console.log(d);
      deffered.resolve();
    });
    return deffered.promise;
  };
  myService.data = function() { return data; };

  return myService;
});

그런 다음 컨트롤러에서 :

app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function() {
    $scope.data = myService.data();
  });
});

답변

tosh shimayama는 해결책이 있지만 $ http가 약속을 반환하고 약속이 가치를 반환 할 수 있다는 사실을 사용하면 단순화 할 수 있습니다.

app.factory('myService', function($http, $q) {
  myService.async = function() {
    return $http.get('test.json')
    .then(function (response) {
      var data = reponse.data;
      console.log(data);
      return data;
    });
  };

  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.asyncData = myService.async();
  $scope.$watch('asyncData', function(asyncData) {
    if(angular.isDefined(asyncData)) {
      // Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
    }
  });

});

커피 스크립트의 작은 데모 : http://plunker.no.de/edit/ksnErx?live=preview

귀하의 plunker가 내 방법으로 업데이트되었습니다 : http://plnkr.co/edit/mwSZGK?p=preview


답변

내가 생각하는 훨씬 더 좋은 방법은 다음과 같습니다.

서비스:

app.service('FruitsManager',function($q){

    function getAllFruits(){
        var deferred = $q.defer();

        ...

        // somewhere here use: deferred.resolve(awesomeFruits);

        ...

        return deferred.promise;
    }

    return{
        getAllFruits:getAllFruits
    }

});

컨트롤러에서 간단히 사용할 수 있습니다.

$scope.fruits = FruitsManager.getAllFruits();

Angular는 자동으로 해결 된 것을에 awesomeFruits넣습니다 $scope.fruits.


답변

나는 같은 문제가 있었지만 인터넷에서 서핑을 할 때 $ http가 기본적으로 약속을 되찾았다는 것을 이해했다. 그리고 나서 “data”를 반환 한 후 “then”으로 사용할 수있다. 코드를보십시오 :

 app.service('myService', function($http) {
       this.getData = function(){
         var myResponseData = $http.get('test.json').then(function (response) {
            console.log(response);.
            return response.data;
          });
         return myResponseData;

       }
});
 app.controller('MainCtrl', function( myService, $scope) {
      // Call the getData and set the response "data" in your scope.  
      myService.getData.then(function(myReponseData) {
        $scope.data = myReponseData;
      });
 });

답변

UI를 배열에 바인딩 할 때 길이를 0으로 설정하고 데이터를 배열로 푸시하여 동일한 배열을 직접 업데이트해야합니다.

이 대신 ( dataUI가 알지 못하는 다른 배열 참조를 설정 ) :

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
    });
  };

이 시도:

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data.length = 0;
      for(var i = 0; i < d.length; i++){
        data.push(d[i]);
      }
    });
  };

다음은 새 배열 설정과 비우기 및 기존 배열 추가의 차이점을 보여주는 바이올린 입니다. 나는 당신의 plnkr을 작동시킬 수 없었지만 희망적으로 이것은 당신을 위해 작동합니다!