Angular.js에서 AJAX 호출을 수행하는 가장 좋은 방법은 무엇입니까?


151

나는이 기사를 읽고 있었다 : http://eviltrout.com/2013/06/15/ember-vs-angular.html

그리고 그것은 말했다

컨벤션이 부족하기 때문에 컨트롤러 내에서 AJAX 호출과 같은 나쁜 관행에 얼마나 많은 Angular 프로젝트가 의존하는지 궁금합니다. 의존성 주입으로 인해 개발자가 라우터 매개 변수를 지시문에 주입합니까? 초보자 AngularJS 개발자는 숙련 된 AngularJS 개발자가 관용적이라고 생각하는 방식으로 코드를 구성하려고합니까?

실제로 $httpAngular.js 컨트롤러에서 전화를 겁니다. 왜 나쁜 습관입니까? 그러면 $http전화를 거는 가장 좋은 방법은 무엇입니까 ? 그리고 왜?


12
ember와 angularjs를 비교하는 흥미로운 게시물을 언급하면 ​​+1입니다.
Chandermani

나는 약 같은 궁금 각도 모범 사례
Dalorzo

또한 보완 기능은 API에서 누락 된 사항을 확인합니다. docs.angularjs.org/api/ng/service/$http
Christophe Roussy

답변:


174

편집 :이 답변은 주로 버전 1.0.X에 중점을 두었습니다. 혼란을 피하기 위해 오늘 2013-12-05 현재 모든 Angular 버전에 대한 최상의 답변을 반영하도록 변경되었습니다.

아이디어는 리턴 된 데이터에 대한 약속을 리턴하는 서비스를 작성한 후 컨트롤러에서이를 호출하여 $ 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;
    });
});

인뷰 약속 해상도 (1.0.X 만 해당) :

여기에 원래 답변의 대상 인 Angular 1.0.X에서 약속은보기에 의해 특별한 대우를받습니다. 이들이 해결되면 해결 된 값이보기에 바인딩됩니다. 이것은 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();
});

4
언급했듯이 $scope.foos템플릿 에서 속성 을 사용할 때만 작동합니다 . 템플릿 외부에서 (예 : 다른 함수에서) 동일한 속성을 사용하는 경우 저장된 개체는 여전히 약속 개체입니다.
Clark Pan

1
현재 새로운 각도 앱 에서이 패턴을 사용하고 있지만 crud 페이지에서 범위에 바인딩 된 속성에 액세스하는 방법을 궁금합니다.이 예제에서는 getFoos에서 데이터를 가져 와서 변경 사항을 게시하려는 경우 그것. 업데이트에서 $ scope.foos에 액세스하려고하면 데이터가 아닌 promise 객체가 있지만 객체 자체에서 데이터를 얻는 방법을 볼 수 있지만 실제로는 해키처럼 보입니다.
Kelly Milligan

5
@KellyMilligan,이 패턴으로, 그것은이의 바인딩 그 약속과 함께 무엇을 알고있다. 다른 곳에서 객체에 액세스해야하는 경우 .then()약속의 약속 을 처리하고 그 가치를 $ scope에 넣어야합니다.myService.getFoos().then(function(value) { $scope.foos = value; });
Ben Lesh

1
1.2.0-rc.3부터이 기술에 대한 업데이트 만 약속의 자동 언 래핑이 더 이상 사용되지 않으므로이 기술은 더 이상 작동하지 않습니다.
Clark Pan

2
최근에 Angular의 최신 버전과 일치하지 않았기 때문에 최근에 여기에 두 개의 다운 보트가 있습니다. 이를 반영하여 답변을 업데이트했습니다.
Ben Lesh

45

가장 좋은 방법은 $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이와 같이 호출을 추상화하면 여러 컨트롤러에서이 코드를 재사용 할 수 있습니다. 이 데이터와 상호 작용하는 코드가 더욱 복잡해지면 컨트롤러에서 데이터를 사용하기 전에 데이터를 처리하고 해당 프로세스의 결과를 캐시하여 다시 처리하는 데 시간을 소비하지 않아도 될 때 필요합니다.

'서비스'는 애플리케이션이 사용할 수있는 데이터의 표현 (또는 모델)로 생각해야합니다.


9

수락 된 대답은 $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) {

1

Angular에서 완전히 일반적인 웹 서비스를 원하는 사람에게 답했습니다. 플러그를 꽂는 것이 좋으며 직접 코딩하지 않아도 모든 웹 서비스 호출을 처리합니다. 대답은 다음과 같습니다.

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.