2013-03-08 25 views
73

Trong góc, chúng tôi có thể tiêm $routeProvider đến config chức nănglàm thế nào để tiêm phụ thuộc vào module.config (configFn) ở góc

module.config(function ($routeProvider) { 


}); 

tôi muốn tiêm dịch vụ của tôi vào nó như

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


}); 

Tôi chắc chắn dịch vụ được xác định đúng cách, nhưng nó ném một ngoại lệ nói rằng unknown myService, sự kiện khi tôi tiêm như

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


}); 

nó vẫn nói unknown $http.

Bạn có biết tại sao không?

+0

bạn có thể tiêm '$ http' cho cấu hình chỉ ví dụ như' $ httpProvider': https://docs.angularjs.org/api/ng/provider/$httpProvider – dewd

Trả lời

91

Từ Modules trang, phần "Mô-đun tải & Dependencies":

Configuration 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.

Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

Vì vậy, bạn không thể tiêm dịch vụ của riêng bạn, hoặc các dịch vụ tích hợp như $ http vào cấu hình(). Sử dụng run() để thay thế.

+0

Cảm ơn cho câu trả lời, nhưng tại sao $ routeProvider có thể được tiêm vào chức năng cấu hình, đây có phải là phụ thuộc duy nhất có thể được đưa vào chức năng cấu hình không? Tôi nghi ngờ điều đó. –

+2

Như đã nêu, bất kỳ "nhà cung cấp" (góc tích hợp, hoặc của riêng bạn) hoặc "liên tục" có thể được tiêm vào hàm config(). Dưới đây là một số mã nguồn góc có chứa các nhà cung cấp tích hợp sẵn: https://github.com/angular/angular.js/blob/79b51d5b578927bd510123c81953e7cc8c72f211/src/AngularPublic.js –

55

Tôi không có đủ danh tiếng để đăng nhận xét nhưng muốn thêm vào câu trả lời của Mark.

Bạn có thể tự đăng ký nhà cung cấp. Về cơ bản chúng là các đối tượng (hoặc các hàm tạo) với phương thức $get. Khi bạn đăng ký một nhà cung cấp, phiên bản tiêu chuẩn của nó có thể được sử dụng như một dịch vụ hoặc nhà máy, nhưng phiên bản nhà cung cấp có thể được sử dụng trước đó. Vì vậy, một nhà cung cấp grumpy được đăng ký như

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

sau đó sẽ có sẵn trong các chức năng cấu hình như

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

và có thể được tiêm vào bộ điều khiển đơn giản là

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

Đối tượng grumpy đó là được tiêm vào myController chỉ đơn giản là kết quả của việc chạy phương pháp $get trên GrumpyProviderObject. Lưu ý, nhà cung cấp mà bạn đăng ký cũng có thể là một hàm tạo JavaScript thông thường.

Lưu ý:. theo nhận xét của @Problematic, rằng khởi cung cấp (các cuộc gọi đến angular.module().provider(…) phải đến trước khi chức năng cấu hình có sẵn

+2

Cảm ơn vì điều này. Cần lưu ý rằng chức năng cấu hình phải đến sau khi nhà cung cấp tiêm nó. Có thể rõ ràng, nhưng nó đã vấp ngã tôi! – Problematic

+0

Cảm ơn bạn vì điều này. Bây giờ tôi thấy rằng các nhà cung cấp chính nó phải được mà không có postfix 'nhà cung cấp'. Cấu hình của tôi đang tìm kiếm ProviderProvider mà nó không thể tìm thấy. –

+2

Điều này cũng sẽ làm việc với 'hằng số', bởi vì hằng số cũng là nhà cung cấp. –

-15

Bạn có thể thử này:

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

Chỉ các Nhà cung cấp và hằng số được phép trong các khối cấu hình để tiêm. Các dịch vụ chưa sẵn sàng cho đến * sau * khối cấu hình được thực thi. –

10

Bạn có thể làm như sau:

(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 */ 

    } 
}); 

Cách tốt nhất là mô tả here

+5

Điều này không hiệu quả đối với tôi. –

+0

Tại sao? Tôi đã làm nó gần đây. –

+1

@DanielKobe .config ('config', config); nên là .config (config); – m1kael

-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: '/' 
     }); 

    }]); 
1

Nếu bạn muốn tiêm phụ thuộc (giả sử từ một dịch vụ) để gọi một dạng hàm trong các tuyến đường (config) như hình dưới đây templateProvider.getTemplate ('about')

.state('index.about', { 

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

}) 

Bạn phải tạo ra một nhà cung cấp. Không phải Dịch vụ hay Nhà máy.

Dưới đây là một ví dụ thực tế của một nhà cung cấp mà tạo ra con đường mẫu từ tên:

(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'; 
        } 

    }; 
})(); 

Việc sử dụng nhà cung cấp như vậy trong các tuyến đường (config) sẽ như sau:

(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'); 
    }; 
})(); 

Lưu ý VIP:

để tiêm nhà cung cấp, bạn phải postfix nó với xxxProvider (tên đó của nhà cung cấp không nên được postfixed, chỉ trên tiêm trong .config).

4

Bạn có thể gọi theo cách thủ công angular.injector để có quyền truy cập vào các dịch vụ không có phụ thuộc trong khối .config() của ứng dụng của bạn. Nếu dịch vụ mà bạn đã tạo không có bất kỳ phụ thuộc mà cần phải được đi qua, thì có thể bạn có thể sử dụng này:

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

này hoạt động cho các dịch vụ đơn giản khác như $http cũng như:

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

Note : Thông thường bạn không cần phải tiêm dịch vụ trong giai đoạn cấu hình của bạn, thiết kế tốt hơn để tạo ra một nhà cung cấp cho phép cấu hình. Các tài liệu nói rằng chức năng này được hiển thị cho các trường hợp thư viện của bên thứ ba cần truy cập vào bộ phun của ứng dụng Góc đã chạy.

+0

Tôi đã thử tính năng này với $ location nhưng vị trí đó không hoạt động. Cung cấp thông báo lỗi "Nhà cung cấp không xác định: $ rootElementProvider". – AndrewR

+2

Khi bạn gọi ['$ injector.get ('serviceName')'] (https://docs.angularjs.org/api/auto/service/$injector#get) trên một dịch vụ chưa được khởi tạo (giống như trong '.config()' block), bộ phun cố gắng khởi tạo dịch vụ đó ngay tại chỗ. Nếu dịch vụ đó có bất kỳ sự phụ thuộc nào, nó sẽ ném một lỗi vì các thông tin đó bị thiếu. Thật không may là bạn không thể cung cấp các phụ thuộc khi bạn gọi '.get()'. '$ location' [có phụ thuộc] (https://github.com/angular/angular.js/blob/master/src/ng/location.js#L671) trên' $ rootElement', do đó, nó có thể ' t được nạp theo cách này. –

-2

Nếu nó có thể giúp mọi người dễ dàng hơn.

Mỗi explained in this answer, bạn chỉ có thể thêm Provider vào dịch vụ tùy chỉnh của mình và sau đó truy cập các chức năng nội bộ bằng cách sử dụng $get().

Nó có thể không phải là giải pháp sạch nhất, nhưng nó thực hiện công việc.

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

Loại không bắt buộcLỗi: $ locationProvider. $ Get không phải là hàm (…) – Gary

+0

Xin chào, bạn sẽ có thể sử dụng '$ locationProvider' vì nó. Nó đã là một nhà cung cấp. Không cần sử dụng hack '$ get()'. Tui bỏ lỡ điều gì vậy? – andrew

+0

Nó không có .path hoặc bất cứ thứ gì, chỉ cần $ get as a Array [6], hàm hashPrefix, và hàm html5Mode. Tôi đang $ injecting '$ locationProvider' vào cấu hình như $ routeProvider. – Gary

Các vấn đề liên quan