コンソールからAngularJSサービスをテストするにはどうすればよいですか?


395

次のようなサービスがあります。

angular.module('app').factory('ExampleService', function(){
  this.f1 = function(world){
    return 'Hello '+world;
  }
  return this;
})

私はしたいと思います JavaScriptコンソールからそれをテストして機能を呼び出すf1()サービスのを。

どうやってやるの?

回答:


713

TLDR:1行で探しているコマンド:

angular.element(document.body).injector().get('serviceName')

ディープダイブ

AngularJSは、依存性注入(DI)を使用して、コンポーネント、ディレクティブ、その他のサービスにサービス/ファクトリーを注入します。サービスを取得するために必要なことは、インジェクターを取得することです、AngularJSを最初(インジェクターはすべての依存関係を関連付け、コンポーネントに提供する責任があります)。

アプリのインジェクターを取得するには、angularが処理している要素からそれを取得する必要があります。たとえば、アプリがbody要素に登録されている場合、次を呼び出しますinjector = angular.element(document.body).injector()

取得したものから、injector好きなサービスを取得できますinjector.get('ServiceName')

この回答の詳細情報:角度からインジェクターを取得できません
さらに詳細:レガシーコードからAngularJSを呼び出す


$scope特定の要素のを取得するためのもう1つの便利なトリック。開発者ツールのDOM検査ツールで要素を選択し、次の行を実行します($0常に選択された要素です):
angular.element($0).scope()


70
私もそれを機能させるためにこれをしなければなりませんでした。ところで、angular.element('*[ng-app]').injector()すべてのケースで動作するはずです。
Francesc Rosas

4
angular.element( 'html')の実行中に「セレクターが実装されていません」というエラーが発生した場合は、Chrome $ 0機能を使用できます。HTML要素を選択し、コンソールに移動して、angular.element($ 0).injector()を実行します
Marek

9
documentまた動作します:angular.element(document).injector().get('serviceName')
Tamlyn

1
FYI私はクロームでdocument.bodyを使用していた
ケビン・

5
FYI私は$ locationサービスを使用したかったのですが、最終的にはそれをscope.applyでラップする必要がありました。私はこれが十分に文書化されていることを知っていますが、それは私の心を滑らせました。1行でangular.element(document).scope()。$ apply(angular.element(document).injector()。get( '$ location')。path( '/ my / angular / url'))
acid_crucifix

25

まず、サービスの修正バージョンです。

a)

var app = angular.module('app',[]);

app.factory('ExampleService',function(){
    return {
        f1 : function(world){
            return 'Hello' + world;
        }
    };
});

これはオブジェクトを返し、ここでは何も新しいものはありません。

これをコンソールから取得する方法は次のとおりです

b)

var $inj = angular.injector(['app']);
var serv = $inj.get('ExampleService');
serv.f1("World");

c)

以前にそこで行っていたことの1つは、app.factoryが関数自体または関数の新しいバージョンを返すと想定することでした。そうではありません。コンストラクタを取得するには、次のいずれかを行う必要があります

app.factory('ExampleService',function(){
        return function(){
            this.f1 = function(world){
                return 'Hello' + world;
            }
        };
    });

これは、次に「新規」を実行する必要があるExampleServiceコンストラクターを返します。

または、代わりに

app.service('ExampleService',function(){
            this.f1 = function(world){
                return 'Hello' + world;
            };
    });

これにより、注入時に新しいExampleService()が返されます。


3
私が行うときvar $inj = angular.injector(['app']);、コンソールはスローError: Unknown provider: $filterProvider from app1つのアプリにしてError: Unknown provider: $controllerProvider from app...他のアプリに
JustGoscha

@JustGoschaアプリはどのように構成されていますか?つまり、どのように行(のように見える)を行うのですかvar app = angular.module( 'app'、[]); アプリのように見えます。
ganaraj 2013年

私は質問を完全に理解していません。それはあなたが言うように見えangular.module('app',[]);、サービス、コントローラーなどが異なるファイルにあり、それらはすべてangular.module('app').factory('FeatureRegistry',function(){//code here});たとえば次のように定義されています
JustGoscha

@JustGoschaこれが私がテストするためにしたことです。chromeでdocs.angularjs.org/apiに行きました。コンソールを開きました。私の回答のセクションaにコードを入力してから、セクションbにコードを入力しました。HelloWorldが表示されます。それを試すことができますか?
ganaraj 2013年

14

@JustGoschaの答えは的確ですが、アクセスしたいときにタイプするのはたくさんあるので、これをapp.jsの下部に追加しました。次に、入力x = getSrv('$http')する必要があるのは、httpサービスを取得することだけです。

// @if DEBUG
function getSrv(name, element) {
    element = element || '*[ng-app]';
    return angular.element(element).injector().get(name);
}
// @endif

それをグローバルスコープに追加しますが、デバッグモードでのみです。私はそれをの中に入れて@if DEBUG、量産コードでそれが終わらないようにしました。 このメソッドを使用して、prouductionビルドからデバッグコードを削除します。


4

Angularjs依存関係注入フレームワークは、アプリモジュールの依存関係をコントローラーに注入する役割を果たします。これは、そのインジェクターを介して可能です。

最初にng-appを識別し、関連するインジェクターを取得する必要があります。以下のクエリは、DOMでng-appを見つけ、インジェクターを取得するために機能します。

angular.element('*[ng-app]').injector()

ただし、Chromeでは、以下に示すようにターゲットng-appをポイントできます。そして$0ハックと問題を使用してangular.element($0).injector()

インジェクターを取得したら、以下のように依存関係が挿入されたサービスを取得します

injector = angular.element($0).injector();
injector.get('$mdToast');

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.