53

複数のページで使用される 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();
    }

}]);
4

5 に答える 5

60

どうやら自動注入を使用していません。ただし、インジェクターを挿入してサービスを確認することはできます。

myApp.controller('MyController', [
    '$scope', '$injector', 'firstRequiredService', 'secondRequiredService', 
    function ($scope, $injector, firstRequiredService, secondRequiredService) {
        if ($injector.has('firstOptionalService')) {
            var firstOptionalService = $injector.get('firstOptionalService');
        }
    }
]);
于 2013-08-30T22:04:39.923 に答える
55

いいえ、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');
    }
});

このプランクでライブをご覧ください。タグで遊んで<script>、コンソール出力を監視してみてください。

$injector.has()PSそして、@Problematicが言ったように、AngularJS 1.1.5から使用できます。

于 2013-08-30T22:03:02.593 に答える