2013-10-04 331 views
31

在提供者方法中可以執行DI嗎?如何使用Angularjs注入依賴到提供者?

在這個例子中

angular.module('greet',[]) 
.provider('greeter',function() { 

    this.$get=function() { 

    }; 
}) 
.service('greeterService',function($http){ 
    console.log($http); 
}) 
; 

注入$http到服務似乎是正確的實現,但它不能在一個供應商的方法工作,它拋出一個錯誤:

Unknown provider: $http

請問提供者方法與DI一起工作來注入服務?

回答

55

您當然可以將$http注入提供程序。只要確保它出現在$get中,而不是函數構造函數。如下:

angular.module('greet',[]).provider('greeter',function() { 
    this.$get = function($http) { 

    }; 
}); 
+1

謝謝。這是否意味着我們不能在$ get之外使用$ http(或其他服務)? – Chung

+0

不,您可以在任何可以注入服務的地方使用$ http。 $ get只是其中之一。 –

+1

以及如何使其縮小可接受? –

2

您實際上必須在$ get中注入依賴關係,然後將其存儲在$ get中檢索的內容上。一點也不漂亮...

3

不,你不能將服務注入提供者本身。 將服務注入提供者的$ get方法與將服務注入工廠的方法相同,但不能直接將其注入提供者函數。

$ get和提供程序本身之間的區別在於提供程序在module loading phase期間運行,而在實例化您提供的服務時運行$ get。

這意味着您不能在模塊的模塊加載/配置階段使用任何服務。這就是你在配置塊中運行的所有東西,比如在定義你的應用程序路徑或狀態時,不能使用任何服務。

除了提供程序之外,您可以注入到配置塊中的唯一其他東西是常量。

你可以做一些像IgrCndd建議的事情。但是,如果您需要在配置塊中使用提供程序(畢竟這是提供程序的目的),那麼您將不會在注入之前注入值。所以,除非你使用promise來做一些令人討厭的黑客攻擊,否則它不會起作用。

Further reading on injectables

9

你可以注入常數和其他供應商到供應商。不是服務或工廠 - 只有一個例外。看起來你可以將$injector服務注入提供者 - 至少,你可以在AngularJS 1.3.16中。

.provider('foo', ['$injector', function ($injector) { 
    var messagePrefix = $injector.get('msgPrefix'); 
    this.message = ''; 

    this.$get = function() { 
    var that = this; 
    return function() { 
     return messagePrefix + that.message; 
    } 
    }; 
}]) 

您可以使用注射器$get方法之外,但仍無法在配置時從它那裏得到的服務。

See here for a demo

6

上IgrCndd的回答跟進,這裏有可能避免潛在的污穢的模式:

angular.module('greet',[]).provider('greeter', function() { 

    var $http; 

    function logIt() { 
     console.log($http); 
    } 

    this.$get = ['$http', function(_$http_) { 
     $http = _$http_; 

     return { 
      logIt: logIt 
     }; 
    }]; 
}); 

注意多麼相似,這是等效的服務,使得兩者之間不太麻煩的轉換:

angular.module('greet',[]).factory('greeter', ['$http', function($http) { 

    function logIt() { 
     console.log($http); 
    } 

    return { 
     logIt: logIt 
    }; 
});