AngularJS와 $ http를 동기화하는 방법
내 초보자 질문에 대해 죄송하지만 AngularJS 설명서는 몇 가지 기본 사항을 파악하기 위해 명시 적이거나 광범위하지 않습니다.
AngularJS와 동기식 호출을 수행하는 방법이 있습니까?
서비스에서 :
myService.getByID = function (id) {
var retval = null;
$http({
url: "/CO/api/products/" + id,
method: "GET"
}).success(function (data, status, headers, config) {
retval = data.Data;
});
return retval;
}
현재는 아닙니다. 소스 코드 를 살펴보면 (이 시점부터 2012 년 10 월 시점) XHR open에 대한 호출이 실제로 비동기식으로 하드 코딩되어 있음을 알 수 있습니다 (세 번째 매개 변수는 true).
xhr.open(method, url, true);
동기식 호출을 수행 한 고유 한 서비스를 작성해야합니다. 일반적으로 JavaScript 실행의 특성으로 인해 다른 모든 것을 차단하게됩니다.
...하지만 .. 다른 모든 것을 차단해야하는 경우 약속과 $ q 서비스를 살펴 봐야 합니다 . 이를 통해 일련의 비동기 작업이 완료 될 때까지 기다렸다가 모두 완료되면 무언가를 실행할 수 있습니다. 유스 케이스가 무엇인지 모르지만 살펴볼 가치가 있습니다.
그 외에, 직접 롤링하려는 경우 동기식 및 비동기식 아약스 호출 방법에 대한 자세한 정보는 여기를 참조하십시오 .
도움이 되길 바랍니다.
Google지도 자동 완성과 약속이있는 공장에서 일했습니다.
http://jsfiddle.net/the_pianist2/vL9nkfe3/1/
이 요청으로 autocompleteService를 출고 전에 $ http incuida로 바꾸면됩니다.
app.factory('Autocomplete', function($q, $http) {
와 $ http 요청
var deferred = $q.defer();
$http.get('urlExample').
success(function(data, status, headers, config) {
deferred.resolve(data);
}).
error(function(data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
<div ng-app="myApp">
<div ng-controller="myController">
<input type="text" ng-model="search"></input>
<div class="bs-example">
<table class="table" >
<thead>
<tr>
<th>#</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="direction in directions">
<td>{{$index}}</td>
<td>{{direction.description}}</td>
</tr>
</tbody>
</table>
</div>
'use strict';
var app = angular.module('myApp', []);
app.factory('Autocomplete', function($q) {
var get = function(search) {
var deferred = $q.defer();
var autocompleteService = new google.maps.places.AutocompleteService();
autocompleteService.getPlacePredictions({
input: search,
types: ['geocode'],
componentRestrictions: {
country: 'ES'
}
}, function(predictions, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
deferred.resolve(predictions);
} else {
deferred.reject(status);
}
});
return deferred.promise;
};
return {
get: get
};
});
app.controller('myController', function($scope, Autocomplete) {
$scope.$watch('search', function(newValue, oldValue) {
var promesa = Autocomplete.get(newValue);
promesa.then(function(value) {
$scope.directions = value;
}, function(reason) {
$scope.error = reason;
});
});
});
the question itself is to be made on:
deferred.resolve(varResult);
when you have done well and the request:
deferred.reject(error);
when there is an error, and then:
return deferred.promise;
var EmployeeController = ["$scope", "EmployeeService",
function ($scope, EmployeeService) {
$scope.Employee = {};
$scope.Save = function (Employee) {
if ($scope.EmployeeForm.$valid) {
EmployeeService
.Save(Employee)
.then(function (response) {
if (response.HasError) {
$scope.HasError = response.HasError;
$scope.ErrorMessage = response.ResponseMessage;
} else {
}
})
.catch(function (response) {
});
}
}
}]
var EmployeeService = ["$http", "$q",
function ($http, $q) {
var self = this;
self.Save = function (employee) {
var deferred = $q.defer();
$http
.post("/api/EmployeeApi/Create", angular.toJson(employee))
.success(function (response, status, headers, config) {
deferred.resolve(response, status, headers, config);
})
.error(function (response, status, headers, config) {
deferred.reject(response, status, headers, config);
});
return deferred.promise;
};
I recently ran into a situation where I wanted to make to $http calls triggered by a page reload. The solution I went with:
- Encapsulate the two calls into functions
- Pass the second $http call as a callback into the second function
- Call the second function in apon .success
Here's a way you can do it asynchronously and manage things like you would normally. Everything is still shared. You get a reference to the object that you want updated. Whenever you update that in your service, it gets updated globally without having to watch or return a promise. This is really nice because you can update the underlying object from within the service without ever having to rebind. Using Angular the way it's meant to be used. I think it's probably a bad idea to make $http.get/post synchronous. You'll get a noticeable delay in the script.
app.factory('AssessmentSettingsService', ['$http', function($http) {
//assessment is what I want to keep updating
var settings = { assessment: null };
return {
getSettings: function () {
//return settings so I can keep updating assessment and the
//reference to settings will stay in tact
return settings;
},
updateAssessment: function () {
$http.get('/assessment/api/get/' + scan.assessmentId).success(function(response) {
//I don't have to return a thing. I just set the object.
settings.assessment = response;
});
}
};
}]);
...
controller: ['$scope', '$http', 'AssessmentSettingsService', function ($scope, as) {
$scope.settings = as.getSettings();
//Look. I can even update after I've already grabbed the object
as.updateAssessment();
And somewhere in a view:
<h1>{{settings.assessment.title}}</h1>
Since sync XHR is being deprecated, it's best not to rely on that. If you need to do a sync POST request, you can use the following helpers inside of a service to simulate a form post.
It works by creating a form with hidden inputs which is posted to the specified URL.
//Helper to create a hidden input
function createInput(name, value) {
return angular
.element('<input/>')
.attr('type', 'hidden')
.attr('name', name)
.val(value);
}
//Post data
function post(url, data, params) {
//Ensure data and params are an object
data = data || {};
params = params || {};
//Serialize params
const serialized = $httpParamSerializer(params);
const query = serialized ? `?${serialized}` : '';
//Create form
const $form = angular
.element('<form/>')
.attr('action', `${url}${query}`)
.attr('enctype', 'application/x-www-form-urlencoded')
.attr('method', 'post');
//Create hidden input data
for (const key in data) {
if (data.hasOwnProperty(key)) {
const value = data[key];
if (Array.isArray(value)) {
for (const val of value) {
const $input = createInput(`${key}[]`, val);
$form.append($input);
}
}
else {
const $input = createInput(key, value);
$form.append($input);
}
}
}
//Append form to body and submit
angular.element(document).find('body').append($form);
$form[0].submit();
$form.remove();
}
Modify as required for your needs.
What about wrapping your call in a Promise.all()
method i.e.
Promise.all([$http.get(url).then(function(result){....}, function(error){....}])
According to MDN
Promise.all waits for all fulfillments (or the first rejection)
참고URL : https://stackoverflow.com/questions/13088153/how-to-http-synchronous-call-with-angularjs
'Programming' 카테고리의 다른 글
λ- 미적분 최적 평가자가 공식없이 큰 모듈 식 지수를 계산할 수있는 이유는 무엇입니까? (0) | 2020.07.01 |
---|---|
ES6 모듈 가져 오기에 옵션 전달 (0) | 2020.07.01 |
검정색 배경에 흰색 텍스트로 프로그래밍 하시겠습니까? (0) | 2020.07.01 |
Mac과 Windows에서 Excel로 CSV 파일을 올바르게 여는 인코딩은 무엇입니까? (0) | 2020.07.01 |
PostgreSQL : 각각 하나의 스키마로 여러 데이터베이스를 사용하거나 여러 스키마로 데이터베이스를 사용하는 것이 더 낫습니까? (0) | 2020.07.01 |