wie man Abhängigkeit in module.config (configFn) im Winkel einfügt


74

In Angular können wir $routeProviderdie configFunktion injizieren

module.config(function ($routeProvider) {


});

Ich möchte meinen Service gerne einbringen

module.config(function ($routeProvider, myService) {


});

Ich bin sicher, dass der Dienst richtig definiert ist, aber es wird eine Ausnahme ausgelöst, die besagt, dass unknown myServiceEreignis, wenn ich wie injiziere

module.config(function ($routeProvider, $http) {


});

es sagt immer noch unknown $http.

Weißt du, warum?


Sie können $httpnur für die Konfiguration injizieren, dh als $httpProvider: docs.angularjs.org/api/ng/provider/$httpProvider
Dewed

Antworten:


95

Auf der Seite "Module", Abschnitt "Laden und Abhängigkeiten von Modulen ":

Konfigurationsblöcke - werden während der Anbieterregistrierungs- und Konfigurationsphase ausgeführt. Nur Anbieter und Konstanten können in Konfigurationsblöcke eingefügt werden. Dies soll verhindern, dass Dienste versehentlich instanziiert werden, bevor sie vollständig konfiguriert wurden.

Blöcke ausführen - werden ausgeführt, nachdem der Injektor erstellt wurde, und werden zum Kickstart der Anwendung verwendet. In Ausführungsblöcke können nur Instanzen und Konstanten eingefügt werden. Dies soll eine weitere Systemkonfiguration während der Laufzeit der Anwendung verhindern.

Sie können also keinen eigenen Dienst oder integrierte Dienste wie $ http in config () einfügen. Verwenden Sie stattdessen run () .


Vielen Dank für die Antwort, aber warum kann $ routeProvider in die Konfigurationsfunktion eingefügt werden? Ist dies die einzige Abhängigkeit, die in die Konfigurationsfunktion eingefügt werden kann? Ich bezweifle das.
Fred Yang

2
Wie bereits erwähnt, kann jeder "Provider" (Angular integriert oder Ihr eigener) oder "Konstante" in die Funktion config () eingefügt werden. Hier ist ein Angular-Quellcode, der die integrierten Anbieter enthält: github.com/angular/angular.js/blob/…
Mark Rajcok

57

Ich habe nicht genug Ruf, um einen Kommentar zu schreiben, wollte aber Marks Antwort ergänzen.

Sie können Anbieter selbst registrieren. Sie sind im Grunde Objekte (oder Konstruktoren) mit einer $getMethode. Wenn Sie einen Anbieter registrieren, kann die Standardversion davon wie ein Dienst oder eine Fabrik verwendet werden, eine Anbieterversion kann jedoch früher verwendet werden. Also ein grumpyAnbieter, der als registriert ist

angular.module('...', [])
    .provider('grumpy', GrumpyProviderObject)

ist dann in der Konfigurationsfunktion als verfügbar

    .config(['grumpyProvider', ..., function (grumpyProvider, ...) { ... }])

und kann einfach als in Steuerungen injiziert werden

    .controller('myController', ['grumpy', ..., function (grumpy, ...) { ... }])

Das grumpyObjekt, in das injiziert wird, myControllerist einfach das Ergebnis der Ausführung der $getMethode auf dem GrumpyProviderObject. Beachten Sie, dass der von Ihnen registrierte Anbieter auch ein regulärer JavaScript-Konstruktor sein kann.

Hinweis: Gemäß dem Kommentar von @Problematic muss die Provider-Initialisierung (der Aufruf von angular.module().provider(…)muss vor der Konfigurationsfunktion erfolgen, um verfügbar zu sein).


4
Danke dafür. Es ist erwähnenswert, dass die Konfigurationsfunktion nach dem Anbieter kommen muss, um sie zu injizieren. Könnte offensichtlich sein, aber es hat mich gestolpert!
Problematisch

1
Danke dafür. Ich sehe jetzt, dass der Provider selbst ohne das Postfix 'Provider' sein muss. Meine Konfiguration suchte nach ProviderProvider, den sie nicht finden konnte.
Etienne Marais

2
Dies funktioniert auch mit constants, da Konstanten auch Anbieter sind.
Patrick Hillert

10

Sie können es so machen:

(function() {
    'use strict';

    angular.module('name', name).config(config);
    // You can do this:
    config.$inject = ['$routeProvider', 'myService'];

    function config($routeProvider, myService) {
        // Or better to use this, but you need to use ng-annotate:
        /* ngInject */

    }
});

Es ist eine bewährte Methode, die hier beschrieben wird


Warum? Ich habe es kürzlich getan.
Lyubimov Roman

1
@DanielKobe .config ('config', config); sollte .config (config) sein;
m1kael

Ja, mein Fehler, ich habe die Antwort bearbeitet. Ich war verwirrt Dienste mit einfacher Konfiguration. Konfigurationen werden nicht wie Dienste injiziert.
Lyubimov Roman

Ich habe es nicht versucht, aber das sollte nicht funktionieren. Es ist nur eine andere Möglichkeit, einen Dienst in einen Konfigurationsabschnitt einzufügen. Wenn es funktioniert, ist es ein Fehler in Angular.
Hgoebl

3
Das sollte nicht funktionieren, ich bin gespannt warum so viele Upvotes? siehe hierConfiguration blocks: get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
Saorikido

5

Sie können manuell anrufen angular.injector, um Zugriff auf Dienste zu erhalten, die während des .config()Blockierens Ihrer App keine Abhängigkeiten aufweisen . Wenn der von Ihnen erstellte Dienst keine Abhängigkeiten aufweist, die durchlaufen werden müssen, können Sie wahrscheinlich Folgendes verwenden:

angular.module('myApp').config(function () {
    var myService = angular.injector(['ng']).get('myService');
});

Dies funktioniert auch für andere einfache Dienste wie $http:

angular.module('myApp').config(function () {
    var http = angular.injector(['ng']).get('$http');
});

Hinweis: Normalerweise sollten Sie während Ihrer Konfigurationsphase keine Dienste einfügen müssen. Es ist besser, einen Anbieter zu erstellen, der die Konfiguration ermöglicht. Die Dokumente sagen, dass diese Funktionalität für Fälle verfügbar ist, in denen Bibliotheken von Drittanbietern Zugriff auf den Injektor einer bereits laufenden Angular-App benötigen.


Ich habe es mit $ location versucht, aber das funktioniert nicht. Gibt eine Fehlermeldung "Unbekannter Anbieter: $ rootElementProvider" aus.
AndrewR

2
Wenn Sie $injector.get('serviceName')einen Dienst aufrufen , der noch nicht instanziiert wurde (wie im .config()Block), versucht der Injektor, diesen Dienst sofort zu instanziieren. Wenn dieser Dienst Abhängigkeiten aufweist, wird ein Fehler ausgegeben, da diese Deps fehlen. Leider können Sie die Abhängigkeiten beim Aufruf nicht angeben .get(). $location hat eine Abhängigkeit von $rootElement, kann also nicht auf diese Weise geladen werden.
Alex Ross

4

Wenn Sie eine Abhängigkeit (z. B. von einem Dienst) einfügen möchten, um ein Funktionsformular in Routen (.config) aufzurufen, wie unten gezeigt templateProvider.getTemplate ('about')

.state('index.about', {  

    url"/about",  
    templateUrl: templateProvider.getTemplate('about'),  
    controller'AboutCtrl',  
    controllerAs'about',  
    data: {pageTitle'About Us Page'}  

})  

Sie müssen einen Provider erstellen. Weder Service noch Fabrik.

Hier ist ein echtes Beispiel eines Anbieters, der den Vorlagenpfad aus dem Namen generiert:

(function ({  

    'use strict';  
    angular  

        .module('mega-app')  

        .provider('template', provider);  

      function provider(CONSTANT{  

        // The provider must include a $get() method This $get() method  
        // will be invoked using $injector.invoke() and can therefore use  
        // dependency-injection.  
       this.$get = function ({  

            return {}  

        };  
       /**  
         * generates template path from it's name  
         *  
         * @param name  
         * @returns {string}  
         */  
       this.getTemplate = function (name{  

            return CONSTANT.TEMPLATES_URL + name + '/' + name + '.html';  
        }  


        /**  
         * generates component path from it's name  
         * @param name  
         * @returns {string}  
         */  
       this.getComponent = function (name{  

            return CONSTANT.COMPONENTS_URL + name + '.html';  
        }  

    };  
})();  

Die Verwendung eines solchen Anbieters in den Routen (.config) ist wie folgt:

(function () {  

    'use strict';  
    angular  

        .module('mega-app')  

        .config(routes);  
   function routes($stateProvider, $urlRouterProvider, templateProvider) {  



       $stateProvider  
            //----------------------------------------------------------------  
            // First State  
            //----------------------------------------------------------------  
            .state('index', {  

                abstract: true,  
                url: "/index",  
                templateUrl: templateProvider.getComponent('content'),  
                controller: 'IndexCtrl',  
                controllerAs: 'index',  
            })  

            //----------------------------------------------------------------  
            // State  
            //----------------------------------------------------------------  
            .state('index.home', {  

                url: "/home",  
                templateUrl: templateProvider.getTemplate('home'),  
                controller: 'HomeCtrl',  
                controllerAs: 'home',  
                data: {pageTitle: 'Home Page'}  

            })  

            //----------------------------------------------------------------  
            // State  
            //----------------------------------------------------------------  
            .state('index.about', {  

                url: "/about",  
                templateUrl: templateProvider.getTemplate('about'),  
                controller: 'AboutCtrl',  
                controllerAs: 'about',  
                data: {pageTitle: 'About Us Page'}  

            })  

        //----------------------------------------------------------------  
        // Default State  
        //----------------------------------------------------------------  
       $urlRouterProvider.otherwise('/index/home');  
    };  
})();  

VIP Hinweis:

Um den Provider zu injizieren, müssen Sie ihn mit xxxProvider postfixieren (dieser Name des Providers sollte nicht postfixiert werden, sondern nur beim Injizieren in die .config).


Ich möchte $ http in meiner Konfiguration aufrufen und eine JSON-Datei abrufen, die Website-Sprachen enthält, und sie dann an die Sprachkonfiguration übergeben. Alle reden über $ get, aber $ get scheint nicht von alleine ausgeführt zu werden Können Sie weitere Informationen bereitstellen? Wenn dieser Anbieter die Konfigurationsdatei ersetzen soll, ist dies der Fall, und wenn er später die Möglichkeit hat, $ http und usw. aufzurufen, tun Sie dies stattdessen?
deadManN

-2

Wenn es einigen von Ihnen die Sache leichter machen kann.

Wie in dieser Antwort erläutert , können Sie einfach Provideran Ihren benutzerdefinierten Dienst anhängen und dann mit auf die internen Funktionen zugreifen $get().

Es ist vielleicht nicht die sauberste Lösung, aber es macht den Job.

module.config(function ($routeProvider, myServiceProvider) {
 // Call a function hello() on myService.
 myServiceProvider.$get().hello();
});

Nicht gefangener TypeError: $ locationProvider. $ Get ist keine Funktion (…)
Gary

Hallo, du solltest das so verwenden können $locationProviderwie es ist. Es ist bereits ein Anbieter. Keine Notwendigkeit, den $get()Hack zu verwenden. Vermisse ich etwas
Andrew

Es hat keinen .path oder irgendetwas, nur. $ Get als Array [6], hashPrefix-Funktion und html5Mode-Funktion. Ich füge '$ locationProvider' wie $ routeProvider in die Konfiguration ein.
Gary

-3
angular.module('modulename').config(['$routeprovider','$controllerprovider',function($routeprovider,$controllerprovider){
angular.module('modulename').controllerProvider = $controllerProvider;
angular.module('modulename').routeprovider=$routeprovider;
$routeprovider.when('/',{
        templateUrl: 'urlname',
        controller: 'controllername',
        resolve:{
             'variable':variablenamewithvalue 
        }
 }).otherwise({
        redirectTo: '/'
      });

  }]);

-15

Sie könnten dies versuchen:

module.config(['$routeProvider', '$http', function ($routeProvider, $http) {}]);

In Konfigurationsblöcken sind nur Anbieter und Konstanten für die Injektion zulässig. Dienste sind erst nach Ausführung des Konfigurationsblocks bereit .
Steven Rogers
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.