$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;
});
};
});
간단하게 하자.처럼 간단하다
- 돌아가다
promise
이용하실 수 있습니다(사용하실 필요가 없습니다).then
사용중) - 사용하다
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으로 설정하고 데이터를 어레이에 푸시하여 동일한 어레이를 직접 업데이트해야 합니다.
)data
UI를 사용합니다.
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
'sourcecode' 카테고리의 다른 글
동일한 값을 여러 변수에 동시에 할당하시겠습니까? (0) | 2022.09.15 |
---|---|
"알림:정의되지 않은 변수", "알림:정의되지 않은 인덱스", "경고:정의되지 않은 배열 키" 및 "알림:PHP를 사용한 정의되지 않은 오프셋" (0) | 2022.09.15 |
Java 7에서의 종료 (0) | 2022.09.15 |
SQLSTATE[HY000 [ 2002 ]라벨 홈스테드 내에서 접속이 거부되었습니다. (0) | 2022.09.15 |
Android: 확인란 수신기 (0) | 2022.09.15 |