複数のページで使用されるAngularJSのコントローラーを実装しようとしています。いくつかのサービスを利用します。それらの一部はすべてのページにロードされますが、一部はロードされません。別のファイルで定義されており、これらのファイルは個別にロードされます。ただし、これらのサービスをすべてのページにロードしないと、エラーが発生します。
Error: Unknown provider: firstOtionalServiceProvider <- firstOtionalService
そのため、すべてのページにスクリプトをロードする必要があります。 Angularで依存関係をオプションとして宣言できますか?例えば:
myApp.controller('MyController', ['$scope', 'firstRequiredService', 'secondRequiredService', 'optional:firstOptionalService', 'optional:secondOptionalService', function($scope, firstRequiredService, secondRequiredService, firstOptionalService, secondOptionalSerivce){
// No need to check, as firstRequiredService must not be null
firstRequiredService.alwaysDefined();
// If the dependency is not resolved i want Angular to set null as argument and check
if (firstOptionalService) {
firstOptionalService.mayBeUndefinedSoCheckNull();
}
}]);
いいえ、Angularはまだオプションの依存関係をサポートしていません。すべての依存関係をモジュールに入れて、1つのJavascriptファイルとしてロードすることをお勧めします。別のJSに別のモジュールを作成し、すべての共通の依存関係を共通のJSに配置することを検討してください。
ただし、説明した動作は _$injector
_ service で実現できます。すべての依存関係の代わりに_$injector
_をコントローラーに挿入し、手動で依存関係をコントローラーからプルして、存在するかどうかを確認します。それでおしまい:
index.html:
_<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<script src="app.js"></script>
<script src="1.js"></script>
<script src="2.js"></script>
<title>1</title>
</head>
<body data-ng-controller="DemoController">
</body>
</html>
_
app.js:
_var myApp = angular.module('myApp', []);
myApp.service('commonService', function(){
this.action = function(){
console.log('Common service is loaded');
}
});
myApp.controller('DemoController', ['$scope', '$injector', function($scope, $injector){
var common;
var first;
var second;
try{
common = $injector.get('commonService');
console.log('Injector has common service!');
}catch(e){
console.log('Injector does not have common service!');
}
try{
first = $injector.get('firstService');
console.log('Injector has first service!');
}catch(e){
console.log('Injector does not have first service!');
}
try{
second = $injector.get('secondService');
console.log('Injector has second service!');
}catch(e){
console.log('Injector does not have second service!');
}
if(common){
common.action();
}
if(first){
first.action();
}
if(second){
second.action();
}
}]);
_
1.js:
_myApp.service('firstService', function(){
this.action = function(){
console.log('First service is loaded');
}
});
_
2.js:
_myApp.service('secondService', function(){
this.action = function(){
console.log('Second service is loaded');
}
});
_
this plunk ! _<script>
_タグで遊んでみて、コンソール出力を監視してください。
追伸そして、@ Problematicが言ったように、AngularJS 1.1.5以降では$injector.has()
を使用できます。
どうやら自動注入を使用していないようです。ただし、インジェクターを注入して、サービスを確認できます。
myApp.controller('MyController', [
'$scope', '$injector', 'firstRequiredService', 'secondRequiredService',
function ($scope, $injector, firstRequiredService, secondRequiredService) {
if ($injector.has('firstOptionalService')) {
var firstOptionalService = $injector.get('firstOptionalService');
}
}
]);
私はおそらく、$ injectorを使用するという@Proplematicの提案に行きます。ただし、考えられる別の解決策があります:すべてのサービスをデフォルト値(null
など)でbootstrap。ファイルに追加します。追加のファイルがロードされると、後の定義デフォルトの定義を上書きし、希望する効果をいくらか作成します。
var app = angular.module('plunker', []);
app.value("service1", null)
.value("service2", null)
.factory("service1", function() { return "hello"; });
app.controller('MainCtrl', function($scope, service1, service2) {
console.log(service1); // hello
console.log(service2); // null
});
これは私がそれを解決した方法です:
var deps = [];
try {
//Check if optionalModule is available
angular.module('app').requires.Push('optionalModule');
deps.Push('optionalModule');
} catch(e){
console.log("Warn: module optionalModule not found. Maybe it's normal");
}
angular.module('app', deps).factory('stuff', function($injector) {
var optionalService;
if($injector.has('optionalService')) {
optionalService = $injector.get('optionalService');
} else {
console.log('No waffles for you, dear sir');
}
});
この方法を試してください。
try {
angular.module('YourModule').requires.Push('Optional dependency module');
} catch(e) {
console.log(e)
}
'requires'は、依存関係モジュールの配列です。