对不起,我的新手问题,但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;
}
Answer 1:
不是现在。 如果你看一下源代码(在时间2012年10月这点) ,你会看到调用XHR开放实际上是硬编码为异步(第三个参数为true):
xhr.open(method, url, true);
你需要编写自己的服务,做到同步调用。 普遍认为,不是你通常会想,因为JavaScript执行你最终阻止一切的性质有关。
...但..如果其他阻止一切实际上是希望的,也许你应该考虑的承诺和$ Q服务 。 它可以让你等到一组异步操作完成后,再执行一次东西他们都完成了。 我不知道你的使用情况是什么,但可能是值得一试。
以外的是,如果你打算推出自己的,更多关于如何使同步和异步Ajax调用信息可以在这里找到 。
我希望这是有帮助的。
Answer 2:
我有一个工厂与谷歌地图自动完成,并作出承诺,我希望你提供集成的工作。
http://jsfiddle.net/the_pianist2/vL9nkfe3/1/
你只需要$ HTTP来替代这个请求autocompleteService 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;
});
});
});
这个问题本身是要进行的:
deferred.resolve(varResult);
当你已经做得很好了,并且请求:
deferred.reject(error);
当有一个错误,然后:
return deferred.promise;
Answer 3:
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;
};
Answer 4:
最近,我遇到了,我想做出一个页面重载触发$ HTTP调用的情况。 我去了解决办法:
- 封装两个电话接入功能
- 通过第二$ HTTP调用作为回调到第二功能
- 调用APON .success第二功能
Answer 5:
这里有一种方法可以做到这一点异步和像你通常会管理的事情。 一切仍是共享的。 你得到你想要更新对象的引用。 每当你更新你的服务,它获取而无需观看或返回一个承诺全局更新。 这是非常好的,因为你可以从服务中更新底层对象而不必重新绑定。 采用了棱角分明它意味着要使用的方式。 我认为这可能是一个坏主意,使$ http.get /后同步。 你会得到脚本明显的延迟。
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();
而在某处一个观点:
<h1>{{settings.assessment.title}}</h1>
Answer 6:
由于同步XHR已被淘汰,最好不要依赖这个。 如果您需要做同步POST请求,您可以使用下面的助手里面的服务来模拟表单POST。
它通过创建与发布到指定的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();
}
修改为需要满足您的需求。
Answer 7:
关于在包装你的电话是什么Promise.all()
方法,即
Promise.all([$http.get(url).then(function(result){....}, function(error){....}])
据MDN
Promise.all等待所有应验(或第一拒绝)
文章来源: How to $http Synchronous call with AngularJS