sourcecode

$http 응답 처리 중 서비스 중

copyscript 2022. 9. 15. 22:50
반응형

$http 응답 처리 중 서비스 중

저는 최근에 SO에서 가 직면한 문제에 대한 자세한 설명을 올렸습니다.실제를 보내지 못했기 때문에$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;
  });
});

비동기이기 때문에$scope는 Ajax 콜이 완료되기 전에 데이터를 취득하고 있습니다.

사용할 수 있습니다.$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 shimyama에는 해결책이 있지만 $1900이 약속을 반환하고 약속이 가치를 반환할 수 있다는 사실을 사용하면 많은 것을 단순화할 수 있습니다.

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
    }
  });

});

cofescript의 간단한 데모

당신의 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는 기본적으로 약속을 되돌려주고, 그 후에 "데이터"를 돌려준 후에 "그때"와 함께 사용할 수 있다는 것을 알았습니다.코드를 확인합니다.

 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을 작동시킬 수 없었지만, 이것이 당신에게 효과가 있기를 바랍니다!

이와 관련하여 비슷한 문제를 겪었지만, Angular가 만든 get or post가 아니라 서드파티(Chrome Extension의 경우)가 만든 연장선입니다.
Chrome Extension을 반환하지 입니다.then()그래서 위의 솔루션에서는 할 수 없었지만 결과는 아직 비동기입니다.
제 입니다.

app.service('cookieInfoService', function() {
    this.getInfo = function(callback) {
        var model = {};
        chrome.cookies.get({url:serverUrl, name:'userId'}, function (response) {
            model.response= response;
            callback(model);
        });
    };
});

그 후 컨트롤러로

app.controller("MyCtrl", function ($scope, cookieInfoService) {
    cookieInfoService.getInfo(function (info) {
        console.log(info);
    });
});

이것이 다른 사람에게도 같은 문제를 일으키는 데 도움이 되기를 바랍니다.

http://markdalgleish.com/2013/06/using-promises-in-angularjs-views/을 읽었습니다.[ Angular ]JS를 사용하면 성공 콜백에서 해결된 값을 수동으로 전달하는 것이 아니라 스코프에 직접 약속을 함으로써 컨트롤러 로직을 합리화할 수 있습니다.]

매우 심플하고 편리:)

var app = angular.module('myApp', []);
            app.factory('Data', function($http,$q) {
                return {
                    getData : function(){
                        var deferred = $q.defer();
                        var promise = $http.get('./largeLoad').success(function (response) {
                            deferred.resolve(response);
                        });
                        // Return the promise to the controller
                        return deferred.promise; 
                    }
                }
            });
            app.controller('FetchCtrl',function($scope,Data){
                $scope.items = Data.getData();
            });

도움이 되었으면 좋겠다

저는 "약속" 방식 때문에 $http를 사용하는 서비스 소비자가 응답을 푸는 방법을 알아야 한다는 사실을 정말 좋아하지 않습니다.

처럼요.$scope.items = Data.getData();현재는 권장되지 않는 방법입니다.

한동안 시도했지만 완벽한 해결책을 내놓지 못했지만, 여기 내 최선의 방법이 있다(플런커).그것은 누군가에게 유용할 수 있다.

app.factory('myService', function($http) {
  var _data;  // cache data rather than promise
  var myService = {};

  myService.getData = function(obj) { 
    if(!_data) {
      $http.get('test.json').then(function(result){
        _data = result.data;
        console.log(_data);  // prove that it executes once
        angular.extend(obj, _data);
      }); 
    } else {  
      angular.extend(obj, _data);
    }
  };

  return myService;
}); 

다음으로 컨트롤러:

app.controller('MainCtrl', function( myService,$scope) {
  $scope.clearData = function() {
    $scope.data = Object.create(null);
  };
  $scope.getData = function() {
    $scope.clearData();  // also important: need to prepare input to getData as an object
    myService.getData($scope.data); // **important bit** pass in object you want to augment
  };
});

이미 발견할 수 있는 단점은

  • 데이터를 추가할 개체를 전달해야 합니다. 이는 Angular에서 직관적이거나 일반적인 패턴이 아닙니다.
  • getData 수 것은 「」입니다.obj(어레이를 는 많은큰입니다.
  • 입력 오브젝트를 해야 합니다.$scope.data= {}$scope.clearData() 또는 ( )의= []어레이에 대응하지 않으면 동작하지 않습니다(이미 어떤 데이터가 전송될지 상정하고 있습니다).는 이 를 IN에서 .getData츠키노

단, 컨트롤러의 "promise unwrap" 보일러 플레이트를 제거하는 패턴을 제공합니다.또한 $http에서 얻은 특정 데이터를 여러 장소에서 DRY 상태로 유지한 채 사용하는 경우에 유용합니다.

서비스 중인 응답 캐싱에 관한 한, 지금까지 본 것보다 더 간단한 버전을 다음에 제시하겠습니다.

App.factory('dataStorage', function($http) {
     var dataStorage;//storage for cache

     return (function() {
         // if dataStorage exists returned cached version
        return dataStorage = dataStorage || $http({
      url: 'your.json',
      method: 'GET',
      cache: true
    }).then(function (response) {

              console.log('if storage don\'t exist : ' + response);

              return response;
            });

    })();

});

또는 """를 합니다.$http.get;

 dataStorage.then(function(data) {
     $scope.data = data;
 },function(e){
    console.log('err: ' + e);
 });

아래 코드를 사용해 주세요.

컨트롤러(PageCtrl)와 서비스(dataService)를 분할할 수 있습니다.

'use strict';
(function () {
    angular.module('myApp')
        .controller('pageContl', ['$scope', 'dataService', PageContl])
        .service('dataService', ['$q', '$http', DataService]);
    function DataService($q, $http){
        this.$q = $q;
        this.$http = $http;
        //... blob blob 
    }
    DataService.prototype = {
        getSearchData: function () {
            var deferred = this.$q.defer(); //initiating promise
            this.$http({
                method: 'POST',//GET
                url: 'test.json',
                headers: { 'Content-Type': 'application/json' }
            }).then(function(result) {
                deferred.resolve(result.data);
            },function (error) {
                deferred.reject(error);
            });
            return deferred.promise;
        },
        getABCDATA: function () {

        }
    };
    function PageContl($scope, dataService) {
        this.$scope = $scope;
        this.dataService = dataService; //injecting service Dependency in ctrl
        this.pageData = {}; //or [];
    }
    PageContl.prototype = {
         searchData: function () {
             var self = this; //we can't access 'this' of parent fn from callback or inner function, that's why assigning in temp variable
             this.dataService.getSearchData().then(function (data) {
                 self.searchData = data;
             });
         }
    }
}());

언급URL : https://stackoverflow.com/questions/12505760/processing-http-response-in-service

반응형