앱 구성, angular.js의 사용자 지정 공급자 내에서 $ http 사용


90

주요 질문-가능합니까? 나는 운없이 시도했다 ..

메인 app.js

...
var app = angular.module('myApp', ['services']);
app.config(['customProvider', function (customProvider) {

}]);
...

공급자 자체

var services = angular.module('services', []);
services.provider('custom', function ($http) {
});

그리고 다음과 같은 오류가 있습니다.

Uncaught Error: Unknown provider: $http from services 

어떤 아이디어?

감사!



사람, 그래 그건 사실이야,하지만 난에 대해 이야기하고있는 app.config부분
KOSMETIKA


나는 또한이 제한에 대해 알고 있지만 어떻게 든 가능 그 내부에 제공 .. 생각
KOSMETIKA

답변:


158

결론은 다음과 같습니다.

  • 당신은 수없는 공급자 구성 섹션에 서비스를 주입 .
  • 당신은 CAN 공급자의 서비스를 초기화하는 섹션으로 서비스를 주입 .

세부:

Angular 프레임 워크에는 2 단계 초기화 프로세스가 있습니다.

1 단계 : 구성

config단계 동안 모든 공급자가 초기화되고 모든 config섹션이 실행됩니다. config섹션 제공자 객체를 구성하고, 따라서 그들이 제공 개체를 주입 할 수있는 코드를 포함 할 수있다. 그러나 공급자는 서비스 개체의 공장이고이 단계에서는 공급자가 완전히 초기화 / 구성 되지 않았기 때문에 ->이 단계에서는 공급자 에게 서비스 생성을 요청할 수 없습니다-> 구성 단계에서는 사용할 수 없습니다 / 주입 서비스 . 이 단계가 완료되면 모든 공급자가 준비됩니다 (구성 단계가 완료된 후에는 공급자 구성을 더 이상 수행 할 수 없음).

2 단계 : 실행

run단계 동안 모든 run섹션이 실행됩니다. 이 단계 에서 공급자는 준비가되어 있으며 서비스를 만들 수 있습니다.-> run단계에서 서비스를 사용 / 주입 할 수 있습니다 .

예 :

1. $http공급자 초기화 기능에 서비스를 삽입하면 작동 하지 않습니다.

//ERRONEOUS
angular.module('myModule').provider('myProvider', function($http) {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function() {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

단계에서 $http실행되는 함수에 서비스 를 주입하려고하므로 config오류가 발생합니다.

Uncaught Error: Unknown provider: $http from services 

이 오류가 실제로 말하는 것은 서비스 $httpProvider를 만드는 데 사용되는이 $http아직 준비되지 않았다는 것입니다.config 단계 ).

주수 2. $http서비스 초기화 기능에 대한 서비스 의지의 작업을 :

//OK
angular.module('myModule').provider('myProvider', function() {
    // SECTION 1: code to initialize/configure the PROVIDER goes here (executed during `config` phase)
    ...

    this.$get = function($http) {
        // code to initialize/configure the SERVICE goes here (executed during `run` stage)

        return myService;
    };
});

이제 서비스를 run단계 동안 실행되는 서비스 초기화 함수에 주입하므로이 코드가 작동합니다.


63
좋은 대답이지만 구성 중에 서비스를 삽입 할 수없는 방법을 설명하지만 구성 중에 HTTP POST / GET을 만드는 방법은 설명하지 않습니다. 이는 API에서 제공하는 값을 사용하여 구성된 애플리케이션에 중요합니다.
Sean O'Dell

3
@bebraw & Kosmetika-구성 단계에서 요청할 필요가 있다고 생각할 수있는 유일한 것은 일종의 설정 개체입니다. API 끝점, 사용자 정보, 사용자의 로케일 및 언어 설정 등이 포함되어있을 수 있습니다.이 경우 해당 정보를 어떻게 든 자바 스크립트 소스에 포함하는 것이 좋습니다. index.html에서 서버 측 렌더링을 사용하여 앱이 초기화되기 전에 사용할 수 있도록 몇 가지 설정을 지정할 수 있습니다. 다른 모든, 나는 그것이-초기화하기가 게시하는 방법을 알아 내려고 시도 할 것
숀 클라크 헤스

2
@Sean : HTTP POST / GET을 만드는 방법은 OP와는 다른 질문입니다 (구성 단계에서 $ http를 사용할 수 있습니까?). 아마도 별도의 게시물이 될 수 있습니다. Angular 구성 단계의 동 기적 특성으로 인해 구성 코드에 서버 측 데이터를 제공하는 좋은 방법은 서버 측 렌더링 (예 :) 중에 HTML 페이지에서 자바 스크립트 객체로 렌더링하는 것 <script>var config = <% = mySettings.toJson() %>;</script>입니다. 이것은 Smarty for PHP, Jinja2 for Python, Nunchucks for NodeJS 등과 같은 템플릿 엔진을 사용하여 수행 할 수 있습니다.
Trevor

4
@threed : 구성 데이터를 서버의 HTML 또는 js에 직접 삽입하는 것은 클라이언트 코드가 동일한 서버에서 온 경우에만 작동합니다. CORS를 사용하면 이제 클라이언트 코드를 다른 서버에서 제공하고 데이터를 별도의 서버에서 제공하는 것이 가능하고 매우 바람직합니다. 이 경우 HTTP를 사용하여 구성 데이터를 검색해야합니다.
Bernard

4
이것은 대답이지만 질문에 대한 대답은 아닙니다.
Eric

64

이것은 당신에게 약간의 영향력을 줄 수 있습니다.

var initInjector = angular.injector(['ng']);
var $http = initInjector.get('$http');

그러나 성공 / 오류 콜백으로 인해 앱 시작과 서버 응답 사이의 경쟁 조건에 놓일 수 있습니다.


6
제 공급자에게 "수용된 답변"이 실패했습니다 ... 저는 희망없이 그 일을하기 위해 2 일 동안 좌절했습니다. 귀하의 접근 방식은 즉시 작동했습니다.
Dave Alperovich

여기서 생성 된 인스턴스가 "실제"서비스 싱글 톤인지 또는 Angular가 실제 인젝터 마법을 수행 할 때 폐기되는 서비스 인스턴스인지 명확히 할 수 있습니까?
에릭

에릭, 지금은 확인할 수 없습니다. 그러나 일반적으로 수행하는 작업 (해당되는 경우)은 서비스 angular.injector(['mymodule'])에이 접근 방식을 사용할 수 있는지 확실하지 않습니다 $http. 그래도 말하고 싶어. 이 도움이 아닌지 확실하지 경우 : - /
코디

2
이것은 받아 들여진 대답이어야합니다. 나는 이것을 작동시키기 위해 노력하는 동안 열심히 노력했고,이 접근 방식은 내 문제를 즉시 해결했습니다. 나는 이것이 매우 일반적인 문제라고 생각합니다. 감사 @Cody
iamdash

5
승인 된 솔루션이 공급자에서 $ http 사용에 대해 작동하지 않음을 확인합니다. 그러나 @Cody의 대답은 트릭하게 수행
디노

1

이것은 오래된 질문입니다. 라이브러리의 핵심 기능에 의존하고 싶다면 닭고기 달걀이 진행되고있는 것 같습니다.

근본적인 방법으로 문제를 해결하는 대신 우회로했습니다. 몸 전체를 감싸는 지시문을 만듭니다. 전의.

<body ng-app="app">
  <div mc-body>
    Hello World
  </div>
</body>

이제 mc-body렌더링하기 전에 (한 번) 초기화해야합니다.

link: function(scope, element, attrs) {
  Auth.login().then() ...
}

Auth 서비스 또는 제공 업체입니다 (예 :

.provider('Auth', function() {
  ... keep your auth configurations
  return {
    $get: function($http) {
      return {
        login: function() {
          ... do something about the http
        }
      }
    }
  }
})

부트 스트랩의 순서를 제어 할 수있는 것 같습니다. 일반 부트 스트랩이 모든 공급자 구성을 해결 한 다음 mc-body지시문 을 초기화하려고합니다 .

그리고이 지시문은 라우팅이 지시문 ex를 통해 주입되기 때문에 라우팅보다 앞서있을 수 있습니다. <ui-route />. 그러나 나는 이것에 대해 틀릴 수 있습니다. 좀 더 조사가 필요합니다.


솔루션에 대해 자세히 설명해 주시겠습니까?
Mark

-2

"아이디어가 있습니까?"라는 질문에 "예"라고 대답했을 것입니다. 하지만 더 있습니다!

구성에서 JQuery를 사용하는 것이 좋습니다. 예를 들면 :

var app = angular.module('myApp', ['services']);
app.config(['$anyProvider', function ($anyProvider) {
    $.ajax({
        url: 'www.something.com/api/lolol',
        success: function (result) {
            $anyProvider.doSomething(result);
        }
    });
}]);

성공 콜백의 $ customProvider에는 내부 공급자 인 것처럼 $가 포함됩니다.
Jeff Fischer

1
내가 $와 $가 아닌 조합을 가지고 있다는 말이 맞습니다. 나는 그것을 모두 $로 업데이트했습니다.
Suamere
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.