Qual è la migliore pratica per effettuare una chiamata AJAX in Angular.js?

Stavo leggendo questo articolo: http://eviltrout.com/2013/06/15/ember-vs-angular.html

E ha detto,

A causa della mancanza di convenzioni, mi chiedo quanti progetti Angular si affidano a cattive pratiche come le chiamate AJAX direttamente all’interno dei controller? A causa dell’iniezione di dipendenza, gli sviluppatori inseriscono i parametri del router in direttive? Gli sviluppatori principianti di AngularJS sono disposti a strutturare il loro codice in un modo che uno sviluppatore esperto di AngularJS crede sia idiomatico?

In realtà sto facendo $http chiamate dal mio controller Angular.js. Perché è una ctriggers pratica? Qual è la migliore pratica per fare chiamate $http allora? e perché?

EDIT: questa risposta era principalmente focalizzata sulla versione 1.0.X. Per evitare che la confusione venga modificata per riflettere la migliore risposta per TUTTE le versioni correnti di Angular a partire da oggi, 2013-12-05.

L’idea è di creare un servizio che restituisca una promise ai dati restituiti, quindi chiamala nel tuo controller e gestisci la promise di inserire la tua proprietà $ scope.

Il servizio

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

Il controller:

Gestire il metodo then() della promise e ricavarne i dati. Imposta la proprietà $ scope e fai qualsiasi altra cosa potresti dover fare.

 module.controller('MyCtrl', function($scope, myService) { myService.getFoos().then(function(foos) { $scope.foos = foos; }); }); 

Risoluzione delle promesse In-View (solo 1.0.X):

In Angular 1.0.X, l’objective della risposta originale qui, le promesse riceveranno un trattamento speciale dalla View. Quando si risolvono, il loro valore risolto sarà associato alla vista. Questo è stato deprecato in 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(); }); 

La migliore pratica sarebbe quella di astrarre la chiamata $http in un “servizio” che fornisce dati al controller:

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

L’astrazione della chiamata $http come questa consentirà di riutilizzare questo codice su più controller. Ciò diventa necessario quando il codice che interagisce con questi dati diventa più complesso, forse si desidera elaborare i dati prima di utilizzarli nel controller e memorizzare nella cache il risultato di tale processo in modo da non dover sprecare tempo a rielaborarlo.

Dovresti pensare al ‘servizio’ come a una rappresentazione (o modello) dei dati che la tua applicazione può utilizzare.

La risposta accettata mi stava dando l’errore $http is not defined quindi ho dovuto fare questo:

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

La principale differenza è questa linea:

 policyService.service('PolicyService', ['$http', function ($http) { 

Ho dato una risposta a qualcuno che voleva un servizio web totalmente generico in Angular. Ti consiglio semplicemente di collegarlo e si prenderà cura di tutte le tue chiamate di servizio web senza doverle codificare tu stesso. La risposta è qui:

https://stackoverflow.com/a/38958644/5349719