[angularjs] app.config에 서비스 삽입

컨트롤러를 호출하기 전에 데이터를 검색 할 수 있도록 app.config에 서비스를 삽입하고 싶습니다. 나는 이것을 이렇게 시도했다 :

서비스:

app.service('dbService', function() {
    return {
        getData: function($q, $http) {
            var defer = $q.defer();
            $http.get('db.php/score/getData').success(function(data) {
                defer.resolve(data);
            });
            return defer.promise;
        }
    };
});

구성 :

app.config(function ($routeProvider, dbService) {
    $routeProvider
        .when('/',
        {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
            resolve: {
                data: dbService.getData(),
            }
        })
});

하지만이 오류가 발생합니다.

오류 : 알 수없는 공급자 : EditorApp의 dbService

설정을 수정하고이 서비스를 주입하는 방법은 무엇입니까?



답변

Alex는 당신이하려는 일을 할 수없는 올바른 이유를 제공했습니다. + 1. 그러나 디자인을 잘 사용하지 않아서이 문제가 발생합니다.

resolve서비스 문자열 또는 주입 할 값을 반환하는 함수를받습니다. 후자를하고 있기 때문에 실제 기능을 전달해야합니다.

resolve: {
  data: function (dbService) {
    return dbService.getData();
  }
}

프레임 워크가 해결 data되면 dbService자유롭게 사용할 수 있도록 함수에 삽입 합니다. 이를 위해 config블록에 전혀 주입 할 필요가 없습니다 .

많이 드세요!


답변

서비스를 사용자 정의 AngularJS 제공자로 설정

허용 대답의 말씀에도 불구하고, 당신은 실제로 CAN 당신이하고자 한 일을하지만 먼저, 당신을 변경 ..이 구성 단계에서 서비스로 사용할 수 그래서, 구성 공급자로 설정해야합니다 Service공급자에 아래 그림과 같이. 여기서 중요한 차이점은의 값 defer을 설정 한 defer.promise후이 속성을 다음이 반환 한 promise 객체로 설정 한다는 것입니다 $http.get.

제공자 서비스 : (제공자 : 서비스 레시피)

app.provider('dbService', function dbServiceProvider() {

  //the provider recipe for services require you specify a $get function
  this.$get= ['dbhost',function dbServiceFactory(dbhost){
     // return the factory as a provider
     // that is available during the configuration phase
     return new DbService(dbhost);
  }]

});

function DbService(dbhost){
    var status;

    this.setUrl = function(url){
        dbhost = url;
    }

    this.getData = function($http) {
        return $http.get(dbhost+'db.php/score/getData')
            .success(function(data){
                 // handle any special stuff here, I would suggest the following:
                 status = 'ok';
                 status.data = data;
             })
             .error(function(message){
                 status = 'error';
                 status.message = message;
             })
             .then(function(){
                 // now we return an object with data or information about error 
                 // for special handling inside your application configuration
                 return status;
             })
    }
}

이제 구성 가능한 사용자 지정 공급자가 있으므로 주입하기 만하면됩니다. 여기서 중요한 차이점은 누락 된 “주사기에 제공자”라는 점입니다.

구성 :

app.config(function ($routeProvider) {
    $routeProvider
        .when('/', {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
            resolve: {
                dbData: function(DbService, $http) {
                     /*
                     *dbServiceProvider returns a dbService instance to your app whenever
                     * needed, and this instance is setup internally with a promise,
                     * so you don't need to worry about $q and all that
                     */
                    return DbService('http://dbhost.com').getData();
                }
            }
        })
});

당신의 해결 된 데이터를 사용 appCtrl

app.controller('appCtrl',function(dbData, DbService){
     $scope.dbData = dbData;

     // You can also create and use another instance of the dbService here...
     // to do whatever you programmed it to do, by adding functions inside the 
     // constructor DbService(), the following assumes you added 
     // a rmUser(userObj) function in the factory
     $scope.removeDbUser = function(user){
         DbService.rmUser(user);
     }

})

가능한 대안

다음 대안은 비슷한 접근 방식이지만 정의가 .config서비스 내에서 발생 하여 앱의 컨텍스트에서 특정 모듈 내로 서비스를 캡슐화 할 수 있습니다. 자신에게 맞는 방법을 선택하십시오. 또한 이러한 모든 것들을 익히는 데 도움이되는 세 번째 대안 및 유용한 링크에 대한 메모는 아래를 참조하십시오.

app.config(function($routeProvider, $provide) {
    $provide.service('dbService',function(){})
    //set up your service inside the module's config.

    $routeProvider
        .when('/', {
            templateUrl: "partials/editor.html",
            controller: "AppCtrl",
            resolve: {
                data:
            }
        })
});

유용한 자료

  • 존 린드 퀴 스트 (John Lindquist)는 egghead.io 에서 훌륭한 5 분 설명 및 데모 를 제공하며 무료 레슨 중 하나입니다! 기본적 $http으로이 요청의 맥락에서 구체적으로 설명하여 데모를 수정했습니다.
  • 제공자 에 대한 AngularJS 개발자 안내서보기
  • factory/ service/ 에 대한 훌륭한 설명도 있습니다.provider clevertech.biz에서가 .

프로 바이더는 .service메소드에 대해 약간 더 많은 구성을 제공하여 애플리케이션 레벨 프로 바이더로서 더 나아지지만 다음 $provide과 같이 구성 에 주입하여 구성 오브젝트 자체 내에이를 캡슐화 할 수도 있습니다 .


답변

짧은 대답 : 당신은 할 수 없습니다. AngularJS는 서비스가 올바르게로드되었는지 확인할 수 없으므로 구성에 서비스를 주입 할 수 없습니다.

이 질문과 답변을보십시오 :
module.config 내부의 AngularJS 의존성 주입

모듈은 부트 스트랩 프로세스 동안 응용 프로그램에 적용되는 구성 및 실행 블록 모음입니다. 가장 간단한 형태로 모듈은 두 종류의 블록으로 구성됩니다.

구성 블록 -공급자 등록 및 구성 단계에서 실행됩니다. 공급자와 상수 만 구성 블록에 주입 할 수 있습니다. 이는 서비스가 완전히 구성되기 전에 실수로 서비스가 인스턴스화되는 것을 방지하기위한 것입니다.


답변

나는 당신이 이것을 할 수 있다고 생각하지 않지만, config블록에 서비스를 성공적으로 주입했습니다 . (AngularJS v1.0.7)

angular.module('dogmaService', [])
    .factory('dogmaCacheBuster', [
        function() {
            return function(path) {
                return path + '?_=' + Date.now();
            };
        }
    ]);

angular.module('touch', [
        'dogmaForm',
        'dogmaValidate',
        'dogmaPresentation',
        'dogmaController',
        'dogmaService',
    ])
    .config([
        '$routeProvider',
        'dogmaCacheBusterProvider',
        function($routeProvider, cacheBuster) {
            var bust = cacheBuster.$get[0]();

            $routeProvider
                .when('/', {
                    templateUrl: bust('touch/customer'),
                    controller: 'CustomerCtrl'
                })
                .when('/screen2', {
                    templateUrl: bust('touch/screen2'),
                    controller: 'Screen2Ctrl'
                })
                .otherwise({
                    redirectTo: bust('/')
                });
        }
    ]);

angular.module('dogmaController', [])
    .controller('CustomerCtrl', [
        '$scope',
        '$http',
        '$location',
        'dogmaCacheBuster',
        function($scope, $http, $location, cacheBuster) {

            $scope.submit = function() {
                $.ajax({
                    url: cacheBuster('/customers'),  //server script to process data
                    type: 'POST',
                    //Ajax events
                    // Form data
                    data: formData,
                    //Options to tell JQuery not to process data or worry about content-type
                    cache: false,
                    contentType: false,
                    processData: false,
                    success: function() {
                        $location
                            .path('/screen2');

                        $scope.$$phase || $scope.$apply();
                    }
                });
            };
        }
    ]);


답변

$ inject service를 사용하여 구성에 서비스를 주입 할 수 있습니다

app.config (function ($ provide) {

    $ provide.decorator ( "$ exceptionHandler", 함수 ($ delegate, $ injector) {
        리턴 함수 (예외, 원인) {
            var $ rootScope = $ injector.get ( "$ rootScope");
            $ rootScope.addError ({message : "Exception", reason : exception});
            $ 대리인 (예외, 원인);
        };
    });

});

출처 : http://odetocode.com/blogs/scott/archive/2014/04/21/better-error-handling-in-angularjs.aspx


답변

** angular.injector를 사용하여 다른 모듈에서 서비스를 명시 적으로 요청하십시오 **

kim3er의 답변 을 자세히 설명 하기 위해 다른 모듈에 포함되어있는 한 서비스, 공장 등을 공급자로 변경하지 않고 서비스를 제공 할 수 있습니다 …

그러나 *Provider각도 지연이 모듈을로드 할 때 (서비스 또는 팩토리를 처리 한 후 내부적으로 각도로 만들어 짐) 항상 사용할 수 있는지 확실하지 않습니다 (먼저로드 된 항목에 따라 다름).

상수로 취급해야하는 값을 다시 주입하려면주의하십시오.

보다 명확하고 신뢰할 수있는 방법 + 작동하는 플런저가 있습니다.

var base = angular.module('myAppBaseModule', [])
base.factory('Foo', function() {
  console.log("Foo");
  var Foo = function(name) { this.name = name; };
  Foo.prototype.hello = function() {
    return "Hello from factory instance " + this.name;
  }
  return Foo;
})
base.service('serviceFoo', function() {
  this.hello = function() {
    return "Service says hello";
  }
  return this;
});

var app = angular.module('appModule', []);
app.config(function($provide) {
  var base = angular.injector(['myAppBaseModule']);
  $provide.constant('Foo', base.get('Foo'));
  $provide.constant('serviceFoo', base.get('serviceFoo'));
});
app.controller('appCtrl', function($scope, Foo, serviceFoo) {
  $scope.appHello = (new Foo("app")).hello();
  $scope.serviceHello = serviceFoo.hello();
});


답변

$ injector를 사용하여 구성에서 서비스 메소드 호출

위와 같이 $ injector 서비스를 사용하여 비슷한 문제가 발생하여 해결했습니다. 서비스를 직접 주입하려고 시도했지만 $ http에 대한 순환 종속성으로 끝났습니다. 이 서비스는 오류가있는 모달을 표시하며 $ https에 의존하는 ui-bootstrap 모달을 사용하고 있습니다.

    $httpProvider.interceptors.push(function($injector) {
    return {
        "responseError": function(response) {

            console.log("Error Response status: " + response.status);

            if (response.status === 0) {
                var myService= $injector.get("myService");
                myService.showError("An unexpected error occurred. Please refresh the page.")
            }
        }
    }