programing

app.config에서 서비스 주입

goodsources 2023. 3. 22. 21:09
반응형

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

설정을 수정하고 이 서비스를 주입하려면 어떻게 해야 합니까?

서비스를 사용자 지정 AngularJS 공급자로 설정

수용된 답변에 따르면 실제로 의도한 작업을 수행할 수 있지만 구성 단계에서 서비스로 사용할 수 있도록 구성 가능한 프로바이더로 설정해야 합니다.첫 번째로 변경하다Service아래 그림과 같이 프로바이더에게 전달합니다.은 「」의 을 입니다.defer을합니다.defer.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);
     }

})

가능한 대체 방법

이지만, 를 the음 the the the the the the the the the the the the the the the the the the the the the로 할 수 있습니다..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
  • 각도 보기프로바이더에 대한 JS 개발자 가이드
  • , 이 부분에 대한 도 있습니다.factory/service/provider clevertech.biz 에 접속해 주세요.

, 보다 ..servicemethod를프로바이더로서 만, .다만, 이것을 config 오브젝트내에 캡슐화할 수도 있습니다.$provide뭇매를 맞다

알렉스는 당신이 하려는 일을 할 수 없는 정확한 이유를 제공했고, 따라서 +1.그러나 이러한 문제가 발생하는 것은 설계 방식을 해결 방법을 잘 사용하지 않기 때문입니다.

resolve는 서비스 문자열 또는 삽입할 값을 반환하는 함수를 사용합니다.후자를 사용하므로 실제 함수를 전달해야 합니다.

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

data 「 」, 「 」, 「 」가됩니다.dbService자유롭게 사용할 수 있도록 함수에 추가했습니다.넣어도 요.config이를 위해 전혀 차단하지 않습니다.

맛있게 드세요!

단답: 할 수 없습니다.각진서비스가 올바르게 로드되었는지 확인할 수 없기 때문에 JS에서는 서비스를 구성에 주입할 수 없습니다.

다음 질문과 답변을 참조하십시오.각선:module.config 내부 값의 JS 의존성 주입

모듈은 부트스트랩 프로세스 중에 응용 프로그램에 적용되는 설정 블록과 실행 블록의 집합입니다.가장 단순한 형태에서 모듈은 두 가지 종류의 블록으로 구성됩니다.

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

될 것 , 했습니다.config)JS 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 서비스를 사용하여 구성 내에서 서비스를 주입할 수 있습니다.

app.config(기능){
$provide.decorator("$exceptionHandler", 함수($delegate, $injector){리턴 함수(실행, 원인){var $rootScope = $injector.get("$rootScope");
$rootScope.addError({message:")예외", 이유: 예외};
$140(예: 원인);
};});
});

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

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

kim3er의 답변을 자세히 설명하자면, 서비스나 공장 등은 다른 모듈에 포함되어 있는 한 프로바이더로 변경하지 않고 제공할 수 있습니다.

이 말이 잘 요.*Provider(서비스 또는 공장에서의 처리 후에 내부에서 앵귤러로 작성됩니다)는, 앵귤러로 모듈을 천천히 로드하기 때문에, 항상 사용할 수 있습니다(그 외의 로드 내용에 따라 다를 수 있습니다).

값을 다시 삽입하려면 상수로 취급해야 합니다.

보다 명확하고 신뢰할 수 있는 방법 + 기능하는 plunker를 소개합니다.

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 부트스트랩모달을 사용하고 있습니다.

    $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.")
            }
        }
    }

매우 간단한 솔루션

주의: 서비스는 설정 실행 시 초기화되지 않기 때문에 비동기 콜 전용입니다.

사용할 수 있습니다.run()방법.예:

  1. 이 서비스의 이름은 "MyService"입니다.
  2. 공급자 "MyProvider"에서 비동기 실행을 위해 사용하려고 합니다.

고객님의 코드:

(function () { //To isolate code TO NEVER HAVE A GLOBAL VARIABLE!

    //Store your service into an internal variable
    //It's an internal variable because you have wrapped this code with a (function () { --- })();
    var theServiceToInject = null;

    //Declare your application
    var myApp = angular.module("MyApplication", []);

    //Set configuration
    myApp.config(['MyProvider', function (MyProvider) {
        MyProvider.callMyMethod(function () {
            theServiceToInject.methodOnService();
        });
    }]);

    //When application is initialized inject your service
    myApp.run(['MyService', function (MyService) {
        theServiceToInject = MyService;
    }]);
});

음, 이번 건은 좀 힘들었지만, 실제로 해냈어요.

각도 변화로 인해 답변이 오래되었는지 모르겠지만 다음과 같이 할 수 있습니다.

다음은 서비스입니다.

.factory('beerRetrievalService', function ($http, $q, $log) {
  return {
    getRandomBeer: function() {
      var deferred = $q.defer();
      var beer = {};

      $http.post('beer-detail', {})
      .then(function(response) {
        beer.beerDetail = response.data;
      },
      function(err) {
        $log.error('Error getting random beer', err);
        deferred.reject({});
      });

      return deferred.promise;
    }
  };
 });

그리고 이게 그 구성입니다.

.when('/beer-detail', {
  templateUrl : '/beer-detail',
  controller  : 'productDetailController',

  resolve: {
    beer: function(beerRetrievalService) {
      return beerRetrievalService.getRandomBeer();
    }
  }
})

가장 쉬운 방법: $injector = angular.element(document.body).injector()

그럼 그걸로 도망가면 돼invoke()또는get()

언급URL : https://stackoverflow.com/questions/15937267/inject-service-in-app-config

반응형