Angular.js'de AJAX çağrısı yapmak için en iyi uygulama hangisidir?


151

Bu makaleyi okuyordum: http://eviltrout.com/2013/06/15/ember-vs-angular.html

Ve dedi ki,

Sözleşmelerin eksikliği nedeniyle, AJAX çağrıları gibi kaç tane Angular projesinin doğrudan kontrolörler içinde kullanıldığını merak ediyorum. Bağımlılık enjeksiyonu nedeniyle, geliştiriciler yönlendirici parametrelerini direktiflere enjekte ediyor mu? Acemi AngularJS geliştiricileri, kodlarını deneyimli bir AngularJS geliştiricisinin deyimsel olduğuna inandığı şekilde yapılandıracak mı?

Aslında $httpAngular.js denetleyicimden arama yapıyorum . Neden kötü bir uygulama? $httpArama yapmak için en iyi uygulama hangisidir? ve neden?


12
Kor ve angularjs karşılaştıran ilginç yazı referans için +1.
Chandermani


Ayrıca bir tamamlayıcı ayrıca kaçırmış olabileceğiniz şeyler için API'yi kontrol edin: docs.angularjs.org/api/ng/service/$http
Christophe Roussy

Yanıtlar:


174

EDIT: Bu cevap öncelikle sürüm 1.0.X odaklanmıştır. Karışıklığı önlemek için, 2013-12-05 itibariyle Angular'ın TÜM güncel sürümleri için en iyi yanıtı yansıtacak şekilde değiştirildi.

Fikir, döndürülen verilere bir söz veren bir hizmet oluşturmak, daha sonra bunu denetleyicinizde çağırmak ve $ scope özelliğinizi doldurmak için söz vermeyi işlemek.

Hizmet

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

Kontrol eden, denetleyici:

Sözün then()yöntemini ele alın ve verileri bundan çıkarın. $ Scope özelliğini ayarlayın ve yapmanız gerekeni yapın.

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

Görüntüleme İçi Vaat Çözünürlüğü (yalnızca 1.0.X):

Buradaki orijinal cevabın hedefi Angular 1.0.X'te, View tarafından özel muamele göreceğine söz veriyor. Çözüldüklerinde, çözümlenen değerleri görünüme bağlanır. 1.2.X sürümünde kullanımdan kaldırıldı

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

4
Sadece, bir $scope.foosözelliği şablonda kullandığınızda çalışır . Aynı özelliği bir şablonun dışında kullanacaksanız (örneğin, başka bir işlevde), orada saklanan nesne hala bir vaat nesnesidir.
Clark Pan

1
Şu anda yeni bir açısal uygulamada bu kalıbı kullanıyorum, ancak bir kaba sayfada, kapsama bağlı olduğum özelliğe nasıl erişileceğini merak ediyorum, bu örnekte getFoos'tan veri almak ve değişiklikleri göndermek istersem o. güncellememde $ scope.foos'a erişmeye çalışırsam, veriyi değil vaat nesnesine sahibim, nesnenin kendisindeki verileri nasıl alacağımı görebilirim, ama gerçekten gerçekten hacky.ideas görünüyor?
Kelly Milligan

5
@KellyMilligan, bu modelde vaatle ne yapacağını bilen bağlayıcıdır . Nesneye başka bir yerden erişmeniz gerekiyorsa .then(), sözün üstesinden gelmek ve değeri $ kapsamına koymak zorunda kalacaksınız ...myService.getFoos().then(function(value) { $scope.foos = value; });
Ben Lesh

1
Sadece 1.2.0-rc.3'ten itibaren bu teknikle ilgili bir güncelleme vaatlerin otomatik olarak kaldırılması kullanımdan kaldırılmıştır, bu nedenle bu teknik artık çalışmayacaktır.
Clark Pan

2
Muhtemelen Angular'ın en son sürümüyle aynı çizgide olmadığı için, son zamanlarda burada birkaç downvotes var. Cevabı yansıtacak şekilde güncelledim.
Ben Lesh

45

En iyi uygulama, $httpçağrıyı kontrol cihazınıza veri sağlayan bir 'hizmet' olarak özetlemektir:

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

Abstracting $httpböyle çağrıyı Birden kontrolörleri arasında bu kodu yeniden sağlayacaktır. Bu, bu verilerle etkileşim kuran kod daha karmaşık hale geldiğinde gerekli olabilir, belki de verileri denetleyicinizde kullanmadan önce işlemek ve bu işlemin sonucunu önbelleğe almak istersiniz, böylece yeniden işlemeye zaman harcamak zorunda kalmazsınız.

'Hizmeti', uygulamanızın kullanabileceği verilerin bir temsili (veya Modeli) olarak düşünmelisiniz.


9

Kabul edilen cevap bana $http is not definedhata veriyor, bu yüzden bunu yapmak zorunda kaldım:

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

Temel fark bu çizgi:

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.