チーム開発のための太字のAngularJSスタイルガイド[1/2]

GoogleのAngularJSガイドラインを読んだ後、その不完全さの印象を受け、クロージャーライブラリを使用することの利益をしばしば示唆しました。 また 、「これらの推奨事項が、AngularJSを使用するすべてのプロジェクトに等しく適用できるとは考えていません。 小規模プロジェクトと大規模プロジェクトの両方に適用できる、より一般的なスタイルガイドのコミュニティからのイニシアチブをご覧いただければ幸いです。」



Angularでの個人的な経験、 いくつかのスピーチ 、およびチーム開発の経験に基づいて、AngularJSのアプリケーションの構文、コーディング、および構造に関するこの大胆なスタイルガイドを紹介します。



モジュール定義



AngularJSのモジュールはさまざまな方法で宣言できます。変数を使用するか、getter構文を使用します。 常に2番目の方法を使用します(さらに、 フレームワークの開発者が推奨します)。



悪い:


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





良い:


 angular .module('app', []) .controller() .factory();
      
      





モジュールの関数とメソッド



Angularモジュールには、 controller



factory



directive



service



など、さまざまなメソッドがあります。また、DIおよびコードのフォーマットに関しては、モジュールのさまざまな構文があります。 名前付き関数の定義を使用して、それらの名前を後で適切なメソッドに渡します。 このメソッドは、関数が匿名ではないため、スタックトレースの機会を増やします(もちろん、匿名関数の代わりに名前付き関数の使用を開始できますが、この方法は読みやすくなっています)。



悪い:


 var app = angular.module('app', []); app.controller('MyCtrl', function () { });
      
      





良い:


 function MainCtrl () { } angular .module('app', []) .controller('MainCtrl', MainCtrl);
      
      





このようなsetter構文を使用して、モジュールを一度定義します: angular.module('app', [])



。 次に、このモジュールにアクセスする必要がある場合(他のファイルなど)、getter構文を使用します: angular.module('app')







また、グローバルスコープを汚染しないように、すべてのコードをIIFEでラップするだけです。



素晴らしい:


 (function () { angular.module('app', []); // MainCtrl.js function MainCtrl () { } angular .module('app') .controller('MainCtrl', MainCtrl); // AnotherCtrl.js function AnotherCtrl () { } angular .module('app') .controller('AnotherCtrl', AnotherCtrl); //   ... })();
      
      





コントローラー



コントローラーはクラスであるため、通常のcontroller



構文に加えて、 controllerAs



構文があります。 このメソッドは、コントローラーインスタンスを参照できることに加えて、スコープをネストするため、正確に使用します。



controllerAsを介したDOMバインディング



悪い:


 <div ng-controller="MainCtrl"> {{ someObject }} </div>
      
      





良い:


 <div ng-controller="MainCtrl as main"> {{ main.someObject }} </div>
      
      





また、 ng-controller



属性を介してDOMにバインドする方法により、指定されたコントローラーとの組み合わせでのみこのビューの使用が大幅に制限されることにも注意してください。 そして、それはまれですが、同じ表現を異なるコントローラーで使用できる状況がまだあります。 この点で柔軟性を高めるには、ルーターを使用してビューをコントローラーと通信します。



素晴らしい:


 <!-- main.html --> <div> {{ main.someObject }} </div> <!-- main.html --> <script> // ... function config ($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl', controllerAs: 'main' }); } angular .module('app') .config(config); //... </script>
      
      





$parent



使用を回避するために、このアプローチで親コントローラーのいずれかにアクセスする必要がある場合、必要なコントローラー(この場合はmain



controllerAs



値を単に記述します。 このメソッドのおかげで、 $parent.$parent



ような呼び出しも回避できることは明らかです。



これはcontrollerAsで



controllerAs



構文は、 $scope



代わりにコントローラーコードでthis



を使用することを意味してい$scope



controllerAs



を使用controllerAs



場合、コントローラーは実際には$scope



結び付けられており、実際にはこの程度の分離を提供します。



悪い:


 function MainCtrl ($scope) { $scope.someObject = {}; $scope.doSomething = function () { }; } angular .module('app') .controller('MainCtrl', MainCtrl);
      
      





prototype



を使用してコントローラークラスを作成することもできますが、各DIプロバイダーはコンストラクターで適切なリンクを必要とするため、これによりコードがすぐに汚染されます。



良い点と悪い点:


継承には適していますが、一般的な使用には適していません。



 function MainCtrl ($scope) { this.someObject = {}; this._$scope = $scope; } MainCtrl.prototype.doSomething = function () { // use this._$scope }; angular .module('app') .controller('MainCtrl', MainCtrl);
      
      





prototype



を使用しているのに理由がわからない場合、これは悪いことです。 prototype



を使用して他のコントローラーから隔離する場合-それは良いことです。 また、一般的な場合、 prototype



を使用するだけで冗長になる場合があります。



良い:


 function MainCtrl () { this.someObject = {}; this.doSomething = function () { }; } angular .module('app') .controller('MainCtrl', MainCtrl);
      
      





上記は、コントローラーでオブジェクトと関数を使用する例を示しています。 もちろん、これはそこでロジックを使用するという意味ではありません...



コントローラーでロジックを使用しない



ロジックを工場とサービスに委任します。



悪い:


 function MainCtrl () { this.doSomething = function () { }; } angular .module('app') .controller('MainCtrl', MainCtrl);
      
      





良い:


 function MainCtrl (SomeService) { this.doSomething = SomeService.doSomething; } angular .module('app') .controller('MainCtrl', MainCtrl);
      
      





このアプローチは、コードの再利用を最大限にし、その機能を確実にカプセル化し、テストをより簡単かつ正確にします。



サービス



サービスはインスタンス化されるため、クラスのようにする必要があります。 そのため、ここでもこれを使用this



、他のすべてに従って関数コードを配置します。



良い:


 function SomeService () { this.someMethod = function () { }; } angular .module('app') .service('SomeService', SomeService);
      
      





工場



ファクトリーは、サービスメソッドを作成するシングルトンモジュールを提供します(たとえば、RESTを介してアプリケーションをサーバーに接続するなど)。 リクエストに応じてオブジェクト全体を作成して返すと、コントローラー内の既存のバインドが更新されたままになり、プリミティブバインドの問題を回避するのにも役立ちます。



重要:実際、「ファクトリー」はテンプレート/実装であり、プロバイダーで識別されるべきではありません。 工場とサービスの両方を「サービス」と呼ぶ方が正しいでしょう。



悪い:


 function AnotherService () { var someValue = ''; var someMethod = function () { }; return { someValue: someValue, someMethod: someMethod }; } angular .module('app') .factory('AnotherService', AnotherService);
      
      





良い:


最初に、関数内に同じ名前のオブジェクトを作成し、次にメソッドで埋めます。 これは、コードのマニュアル文書化と自動化された手段による文書生成の両方に貢献します。



 function AnotherService () { var AnotherService = {}; AnotherService.someValue = ''; AnotherService.someMethod = function () { }; return AnotherService; } angular .module('app') .factory('AnotherService', AnotherService);
      
      





ここでは、プリミティブへのすべてのバインディングが更新されたままであり、これにより内部モジュールの名前空間の構成が少しわかりやすくなります。ここでは、プライベートメソッドとプライベート変数をすぐに見ることができます。



継続するには...



翻訳の次の部分では:



継続



このスタイルガイドは、最終段階にあります。 常に最新の推奨事項がGithubにあります。



All Articles