Какова наилучшая практика для вызова AJAX в Angular.js?
Я читал эту статью: http://eviltrout.com/2013/06/15/ember-vs-angular.html
И он сказал:
Из-за отсутствия соглашений, интересно, сколько проектов Angularполагаться на плохие практики, такие как AJAX-вызовы непосредственно внутри контроллеров? Из-за инъекции зависимости, разработчики вводят роутер параметры в директивы? Являются ли начинающие разработчики AngularJS структурировать свой код таким образом, чтобы опытный разработчик AngularJS считает, что идиоматический?
Я действительно звоню $http
из моего контроллера Angular.js. Почему это плохая практика? Какова наилучшая практика для создания вызовов $http
? и почему?
Ответы
Ответ 1
EDIT: этот ответ был в основном сосредоточен на версии 1.0.X. Чтобы предотвратить путаницу, он изменяется, чтобы отобразить лучший ответ для ВСЕХ текущих версий Angular на сегодняшний день, 2013-12-05.
Идея заключается в создании службы, которая возвращает обещание возвращенным данным, а затем вызывает это в вашем контроллере и обрабатывает обещание там заполнить ваше свойство $scope.
Сервис
module.factory('myService', function($http) {
return {
getFoos: function() {
//return the promise directly.
return $http.get('/foos')
.then(function(result) {
//resolve the promise as the data
return result.data;
});
}
}
});
Контроллер:
Обработать метод обещания then()
и получить данные из него. Задайте свойство $scope и сделайте все, что вам может понадобиться.
module.controller('MyCtrl', function($scope, myService) {
myService.getFoos().then(function(foos) {
$scope.foos = foos;
});
});
Разрешение Promise в режиме просмотра (только 1.0.X):
В Angular 1.0.X, цель первоначального ответа здесь, promises, получит вид View. Когда они разрешат, их разрешенная ценность будет привязана к виду. Это устарело в 1.2.X
module.controller('MyCtrl', function($scope, myService) {
// now you can just call it and stick it in a $scope property.
// it will update the view when it resolves.
$scope.foos = myService.getFoos();
});
Ответ 2
Лучшей практикой было бы абстрактное обращение $http
к "службе", которая предоставляет данные вашему контроллеру:
module.factory('WidgetData', function($http){
return {
get : function(params){
return $http.get('url/to/widget/data', {
params : params
});
}
}
});
module.controller('WidgetController', function(WidgetData){
WidgetData.get({
id : '0'
}).then(function(response){
//Do what you will with the data.
})
});
Тестирование вызова $http
, как это, позволит вам повторно использовать этот код для нескольких контроллеров. Это становится необходимым, когда код, который взаимодействует с этими данными, становится более сложным, возможно, вы хотите обработать данные перед его использованием в своем контроллере и кэшировать результат этого процесса, чтобы вам не пришлось тратить время на его повторную обработку.
Вы должны думать о "службе" как о представлении (или модели) данных, которое может использовать ваше приложение.
Ответ 3
Принятый ответ дал мне ошибку $http is not defined
, поэтому мне пришлось это сделать:
var policyService = angular.module("PolicyService", []);
policyService.service('PolicyService', ['$http', function ($http) {
return {
foo: "bar",
bar: function (params) {
return $http.get('../Home/Policy_Read', {
params: params
});
}
};
}]);
Основное отличие этой строки:
policyService.service('PolicyService', ['$http', function ($http) {
Ответ 4
Я поставил ответ для тех, кто хотел получить полностью общий веб-сервис в Angular. Я бы порекомендовал просто подключить его, и он позаботится обо всех ваших вызовах веб-сервисов, не заставляя их кодировать самостоятельно. Ответ здесь:
fooobar.com/info/41964/...