1。依存関係注射
依存関係インジェクション(DI)は、コードが依存するリソースをどのように取得するかを扱うソフトウェアデザインパターンです。
DIに関するより深い議論のために、依存関係の注入(http://en.wikipedia.org/wiki/dependency_injection)、コントロールの反転(http://martinfowler.com/articles/injection.html)にアクセスすることも、ソフトウェアの設計パターンの本にアクセスすることもできます。
1。一言で言えばディ(単に話すだけです)
オブジェクトまたは関数は、次の3つの方法で依存するリソースのみを取得できます。
1)新しいオペレーターを介して依存リソースを作成できます。
2)グローバル変数を介して従属リソースを見つけることができます。
3)従属リソースは、パラメーターに渡すことができます。
2つのメソッド1と2は、依存関係をハードコーディングするため、依存関係を変更することは不可能ではありませんが、より複雑になるため、最良ではありません。これは特にテストの問題であり、通常は独立してテストする場合は、模擬依存関係を提供することが望まれます。
3番目の方法は、コンポーネントから依存関係を見つける責任を削除するため、比較的実現可能です。信頼はコンポーネントに引き渡されます。
function someclass(greeder){this.greeter = greeter} someclass.prototype.dosomething = function(name){this.greeter.greet(name);}上記の例では、SomeClassは挨拶の依存関係を見つけることを気にする必要はなく、実行時にのみ挨拶をします。
これはより適切ですが、SomeClassの構築を担当するコードに依存関係リソースを取得する責任を残します。
依存関係を作成する責任を管理するために、各Angularアプリケーションにはインジェクター(http://code.angularjs.org/1.0.2/docs/api/angular.injector)があります。インジェクターは、従属リソースの検索と作成を担当するサービスロケーターです。
依存関係を要求し、ハードコードの問題を解決しますが、インジェクターがアプリケーション全体を実行する必要があることを意味します。渡すインジェクターは、デメテルの法則を破壊します(http://baike.baidu.com/view/823220.htm)。この問題を修正するために、依存関係検索の責任をインジェクターに転送します。
私は上記でたくさん言った。以下に変更した例を見てください。元のテキストの2つの例を統合しました。
<!doctype html> <html lang = "zh-cn" ng-app = "mainapp"> <head> <head> <heats charset = "utf-8"> <title> injector </head> </head> <body> src = "../ angular-1.0.1.js" type = "text/javascript"> </script> <script type = "text/javascript"> //外部モジュールvar othermodule = angular.module( "othermodule"、[]); // Injectorを授ける方法「Greeter」の作成方法//以下は、非電流モジュールで、インジェクターを介して挨拶メソッドを呼び出すことを示しています。//モジュールから新しいインジェクターを作成する//このステップは通常、Angularの起動時に自動的に実行されます。 // 'ng'、角度のものを導入する必要があります//注文は意図的に逆転し、このことの順序が重要ではないことが一時的に確認されます。 。 var injector = angular.injector(['othermodule'、 'ng']); // Greeterの依存関係を要求します。 var g = injector.get( "Greeter"); //それを直接呼び出す〜G.Greet( "Hi〜my Little dada〜"); //これは現在のメインアプリであり、他のモジュールvar mainapp = angular.module( "mainapp"、["othermodule"])に依存する必要があります。 //コントローラーの定義関数のパラメーターに注意を払い、ここから$スコープとグリーターを直接注入します。 // Greeter Serviceはmainapp.controller( "mycontroller"、function mycontroller($ scope、greeder){$ scope.sayhello = function(){greeder.greet( "hello kitty ~~");};}); // ng-controllerは舞台裏で静かにこのことを行った//injector.instantiate(mycontroller); </script> </body> </html>NGコントローラーがあるため、MyControllerが初期化されているため、MyControllerのすべての依存関係を満たすことができるため、MyControllerはインジェクターの存在を知る必要がないことに注意してください。これが最良の結果です。アプリケーションコードは、インジェクターを処理せずに必要な依存関係を単に要求します。この設定は、デメテルの法則を破ることはありません。
2。依存関係の注釈(依存関係のコメント、依存関係の方法の説明)
インジェクターは、どのサービスを注入する必要があるかをどのように把握していますか?
アプリケーション開発者は、依存関係のソリューションとしてインジェクターで使用される注釈情報を提供する必要があります。 Angularの既存のAPI関数はすべてインジェクターを参照しており、これは各ドキュメントに記載されているAPIの場合です。コードにサービス名情報を注釈する3つの同等の方法を以下に示します。
1。依存関係の推測
これは、従属リソースを取得する最も簡単な方法ですが、関数のパラメーター名が従属リソースの名前と一致していると仮定する必要があります。
function mycontroller($ scope、greeder){...}関数のインジェクターは、関数定義をチェックし、関数名を抽出することにより、注入する必要があるサービスの名前(functionname.tostring()、regexp)を推測できます。上記の例では、$スコープとグリーターは、関数に注入する必要がある2つのサービスです(名前も同じです)。
これは簡単ですが、この方法は、パラメーター名が変更されるため、JavaScriptの難読化後に機能しません。 This makes this method only useful for pretotyping (product usability prototype simulation test method, http://www.pretotyping.org/, http://tech.qq.com/a/20120217/000320.htm) and demo applications.
2。$ inject annotation($ injectコメント)
スクリプトコンプレッサーが関数のメソッドの名前を変更し、正しいサービスを挿入できるようにするために、$ injectプロパティを介して依存関係についてコメントする必要があります。 $ injectプロパティは、注入する必要があるサービスの名前の配列です。
var mycontroller = function($ scope、ranamedgreeter){...} //ここで依存しているものが現在のモジュールにない場合でも、それを認識していません。 //最初に現在のモジュールの対応するモジュールに依存する必要があります。前の例に似ています。しかし、これが正しい方法であるかどうかはわかりません。
myController。$ inject = ['$ scope'、 'greeter'];
$ injectの順序は、関数によって宣言された引数の順序と一致する必要があることに注意する必要があります。
この注釈方法は、関数を使用して注釈情報を指定するため、コントローラー宣言に役立ちます。
3。インライン注釈(インラインコメント)
直接コメントするときなど、$ Inject Annotationメソッドを使用すると便利ではない場合があります。
例えば:
somemodule.factory( 'Greeter'、function($ window){...;});一時的な変数が必要であるため(圧縮後に使用できないことを防ぎます)、コードは次のように膨れます。
var greeterfactory = function(named $ window){...;}; greeterfactory。$ inject = ['$ window']; somemodule.factory( 'greeter'、greeterfactory);このため(コード肥大化)、Angularは3番目のコメントスタイルも提供します。
somemodule.factory( 'Greeter'、['$ window'、function(neame heame $ window){...;}]);すべてのコメントスタイルは同等であり、注入をサポートする角度のどこでも使用できることを忘れないでください。
3.どこでdiをユーザーに使用できますか?
diは角度全体にあります。通常、コントローラーおよび工場の方法で使用されます。
1。コントローラーのDI
コントローラーは、アプリケーションの動作を(説明する)責任を負うクラスです。推奨されるコントローラー宣言方法は次のとおりです。
var mycontroller = function(dep1、dep2){...} mycontroller。$ inject = ['dep1'、 'dep2']; prototype.amethod = function(){...}}2。工場の方法
工場の方法は、ほとんどの角度オブジェクトを作成する責任があります。たとえば、指令、サービス、フィルター。工場メソッドはモジュールに登録されています。推奨される工場宣言方法は次のとおりです。
Angualar.module( 'mymodule'、[])。 config(['depprovider'、function(depprovider){...}])。 Factory( 'ServiceId'、['Devervice'、function(depservice){...}])。ディレクティブ( 'directivename'、['depservice'、function(depservice){...}])。 filter( 'filtername'、['devervice'、function(depservice){...}]);上記は、AngularJS依存関係の注入情報の概要です。このサイトへのご支援ありがとうございます!