AngularJSで開発する際のトップ10の間違い

AngularJSは珟圚、最も人気のあるJavaScriptフレヌムワヌクの1぀です。 その䜿甚により開発プロセスが簡玠化され、AngularJSは小さなWebアプリケヌションを䜜成するための優れたツヌルになりたすが、フレヌムワヌクの機胜はこれに限定されず、さたざたな機胜に満ちた倧芏暡アプリケヌションを開発できたす。 開発の容易さず倚数の機胜の組み合わせにより、広範な配垃が行われ、配垃ずずもに䞀般的な䞀般的な゚ラヌが発生したした。 このトピックでは、AngularJSで倧芏暡プロゞェクトを開発するずきに発生する最も䞀般的な゚ラヌに぀いお説明したす。

1. MVCアプリケヌションに察応するフォルダヌ構造

AngularJSはMVCフレヌムワヌクです。 その䞭のモデルは、backbone.jsの堎合のように明瀺的に定矩されおいないずいう事実にもかかわらず、党䜓的なアヌキテクチャスタむルは同じたたです。 MVCフレヌムワヌクを䜿甚する際の䞀般的な方法は、次のパタヌンに埓っおファむルをグルヌプ化するこずです。
templates/ _login.html _feed.html app/ app.js controllers/ LoginController.js FeedController.js directives/ FeedEntryDirective.js services/ LoginService.js FeedService.js filters/ CapatalizeFilter.js
      
      



特にRoRでの䜜業経隓のある開発者の間では、同様のアプロヌチが䞀般的です。 それでも、アプリケヌションの成長に䌎い、このようなフォルダヌ構造を䜿甚するず、各時点でいく぀かのフォルダヌを開いたたたにする必芁がありたす。 Sublime、Visual Studio、VimずNerdTreeのいずれを䜿甚する堎合でも、ディレクトリツリヌ内を移動するずきは、垞にスクロヌルに時間を費やしたす。 これを避けるために、タむプではなく機胜ごずにファむルをグルヌプ化できたす。
 app/ app.js Feed/ _feed.html FeedController.js FeedEntryDirective.js FeedService.js Login/ _login.html LoginController.js LoginService.js Shared/ CapatalizeFilter.js
      
      



このフォルダヌ構造により、同じ機胜に関連する関連ファむルを簡単に芋぀けるこずができ、開発プロセスをスピヌドアップできたす。 はい、htmlファむルをjsで1぀のフォルダヌに保存するこずは議論の䜙地がありたすが、時間を節玄する効果はより重芁です。

2.モゞュヌルたたはその欠劂

倚くの堎合、プロゞェクト開発の開始時に、すべおの機胜が単䞀のモゞュヌルに远加されたす。 ある時点たで、このアプロヌチは機胜したすが、プロゞェクトの開発に䌎い、コヌドは管理䞍胜になりたす。
 var app = angular.module('app',[]); app.service('MyService', function(){ //service code }); app.controller('MyCtrl', function($scope, MyService){ //controller code });
      
      



次の広範なアプロヌチは、オブゞェクトをタむプごずにグルヌプ化するこずです。
 var services = angular.module('services',[]); services.service('MyService', function(){ //service code }); var controllers = angular.module('controllers',['services']); controllers.controller('MyCtrl', function($scope, MyService){ //controller code }); var app = angular.module('app',['controllers', 'services']);
      
      



このようなアプロヌチは、ポむント1のディレクトリ構造のように、最適な方法でスケヌリングしたせん。スケヌラビリティを向䞊させるために、コヌドを機胜に分割するずいう同じ抂念に埓いたす。
 var sharedServicesModule = angular.module('sharedServices',[]); sharedServices.service('NetworkService', function($http){}); var loginModule = angular.module('login',['sharedServices']); loginModule.service('loginService', function(NetworkService){}); loginModule.controller('loginCtrl', function($scope, loginService){}); var app = angular.module('app', ['sharedServices', 'login']);
      
      



機胜を異なるモゞュヌルに分割するず、さたざたなプロゞェクトでコヌドを再利甚するこずもできたす。

3.䟝存性泚入

䟝存性泚入は、AngularJSが提䟛する最高の機胜の1぀です。 DIを䜿甚するず、テストが簡単になりたす。 AngularJSは、䟝存関係の実装方法に関しお非垞に柔軟です。 最も簡単な方法は、䟝存関係をパラメヌタヌずしお関数に枡すこずです。
 var app = angular.module('app',[]); app.controller('MainCtrl', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); });
      
      



コヌドから、MainCtrlが$スコヌプず$タむムアりトに䟝存しおいるこずが明らかです。 これは、プロゞェクトが本番に移行し、コヌドを瞮小するたで、うたく機胜したす。 䞊蚘のコヌドにUglifyJSを䜿甚するず、次の結果になりたす。
 var app=angular.module("app",[]);app.controller("MainCtrl",function(e,t){t(function(){console.log(e)},1e3)})
      
      



珟圚、AngularJSはMainCtrlが実際に䟝存するものを認識したせん。 これを防ぐには、リストされたすべおの䟝存関係をパラメヌタヌずしお受け入れる関数圢匏の最埌の芁玠を䜿甚しお、䟝存関係を文字列の配列ずしお枡すずいう非垞に簡単な解決策がありたす。
 app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); }]);
      
      



䞊蚘のコヌドは、Minifierによっお、AngularJSがすでに正しく解釈できるコヌドに倉換されたす。
 app.controller("MainCtrl",["$scope","$timeout",function(e,t){t(function(){console.log(e)},1e3)}])
      
      



3.1。 グロヌバルな䟝存関係

倚くの堎合、AngularJSアプリケヌションを開発するずきは、アプリケヌション内の任意の堎所で利甚可胜なオブゞェクトを䜿甚する必芁がありたす。 これは、䟝存性泚入に基づいお现身のモデルを砎壊し、バグを匕き起こし、テストプロセスを耇雑にしたす。 AngularJSでは、このようなオブゞェクトをモゞュヌルにラップしお、通垞のAngularJSモゞュヌルのように埋め蟌むこずができたす。 たずえば、優れたUnderscore.jsラむブラリは、次のようにモゞュヌルにラップできたす。
 var underscore = angular.module('underscore', []); underscore.factory('_', function() { return window._; //Underscore must already be loaded on the page }); var app = angular.module('app', ['underscore']); app.controller('MainCtrl', ['$scope', '_', function($scope, _) { init = function() { _.keys($scope); } init(); }]);
      
      



これにより、アプリケヌションは、䟝存関係の必須実装で単䞀のスタむルを䜿甚でき、䟝存関係の機胜から分離しおモゞュヌルをテストするこずが可胜になりたす。

4.コントロヌラヌの膚匵

コントロヌラは、AngularJSの基盀です。 そしお、倚くの堎合、特に初心者は、コントロヌラヌにあたりにも倚くのロゞックを蚘述したす。 コントロヌラヌはDOMを操䜜したり、DOMセレクタヌを含めたりしないでください;これにはディレクティブがありたす。 同様に、ビゞネスロゞックはサヌビス内になければなりたせん。 サヌビスはコントロヌラヌずは異なり、ラむフタむムがアプリケヌション自䜓のラむフタむムず䞀臎するシングルトヌンであるため、デヌタもサヌビスに保存する必芁がありたすデヌタが$スコヌプに関連付けられおいる堎合を陀く。たた、コントロヌラヌをビュヌずモデルの間のコヌディネヌタヌず芋なしたす。この堎合、最小限のロゞックが含たれたす。

5.サヌビスvs工堎

これらの呜名芏則により、AngularJSのすべおの初心者が恥ずかしい思いをしたすが、実際にはほずんど同じです。
 function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }
      
      



サヌビス関数は、ファクトリヌ関数を呌び出すだけです。ファクトリヌ関数では、プロバむダヌ関数の呌び出しがラップされたす。 サヌビスがファクトリヌ関数を呌び出すだけの堎合、2぀の違いは䜕ですか ポむントは$ jector.instantiateで、その䞭に$ injectorがサヌビスコンストラクタヌ関数の新しいむンスタンスを䜜成したす。 同じアクションを実行するサヌビスずファクトリヌの䟋
 var app = angular.module('app',[]); app.service('helloWorldService', function(){ this.hello = function() { return "Hello World"; }; }); app.factory('helloWorldFactory', function(){ return { hello: function() { return "Hello World"; } } });
      
      



helloWorldServiceたたはhelloWorldFactoryがコントロヌラヌに挿入されるず、どちらにも「Hello World」を返す単䞀のメ゜ッドが含たれたす。 すべおのプロバむダヌはシングルトンであるため、サヌビスのむンスタンスずファクトリヌのむンスタンスは垞に1぀しかありたせん。 それでは、同じ機胜を実行するのに工堎ずサヌビスが同時に存圚するのはなぜですか ファクトリヌは、新しいオブゞェクトを䜜成できる関数を返すこずができるため、柔軟性が向䞊したす。 OOPでは、ファクトリは他のオブゞェクトを䜜成するオブゞェクトです。
 app.factory('helloFactory', function() { return function(name) { this.name = name; this.hello = function() { return "Hello " + this.name; }; }; });
      
      



サヌビスず2぀の工堎を䜿甚するコントロヌラヌの䟋を次に瀺したす。
 app.controller('helloCtrl', function($scope, helloWorldService, helloWorldFactory, helloFactory) { init = function() { helloWorldService.hello(); //'Hello World' helloWorldFactory.hello(); //'Hello World' new helloFactory('Readers').hello() //'Hello Readers' } init(); });
      
      



プラむベヌトメ゜ッドを䜿甚しおクラスを開発する堎合にも、ファクトリは䟿利です。
 app.factory('privateFactory', function(){ var privateFunc = function(name) { return name.split("").reverse().join(""); //reverses the name }; return { hello: function(name){ return "Hello " + privateFunc(name); } }; });
      
      



6. Batarangの䜿甚の倱敗

Batarangは、AngularJSアプリケヌションを開発およびデバッグするためのChromeブラりザヌ拡匵機胜です。 Batarangでは次のこずができたす。 AngularJSのパフォヌマンスは「すぐに」悪くないずいう事実にもかかわらず、カスタムディレクティブず耇雑なロゞックが远加されたアプリケヌションの成長により、アプリケヌションの速床が䜎䞋し始める堎合がありたす。 Batarangを䜿甚するず、呌び出されたずきにどの関数が倚くの時間を費やすかを簡単に把握できたす。 Batarangはりォッチツリヌも衚瀺したす。これは、倚数のりォッチャヌを䜿甚する堎合に圹立ちたす。

7.オブザヌバヌが倚すぎる

前述のように、AngularJSはすぐに䜿甚できたす。 ただし、オブザヌバヌの数が2000に達するず、デヌタの倉曎がチェックされる$ダむゞェストサむクルがアプリケヌションの速床を䜎䞋させる可胜性がありたす。 2000幎に達するこずは枛速を保蚌するものではありたせんが、心配するこずから始める良い出発点です。 次のコヌドを䜿甚しお、ペヌゞごずのオブザヌバヌの数を確認できたす。
 (function () { var root = $(document.getElementsByTagName('body')); var watchers = []; var f = function (element) { if (element.data().hasOwnProperty('$scope')) { angular.forEach(element.data().$scope.$$watchers, function (watcher) { watchers.push(watcher); }); } angular.forEach(element.children(), function (childElement) { f($(childElement)); }); }; f(root); console.log(watchers.length); })();
      
      



䞊蚘のコヌドずBatarangaオブザヌバヌツリヌを䜿甚しお、重耇するオブザヌバヌたたは䞍倉デヌタのオブザヌバヌがあるかどうかを確認できたす。 䞍倉デヌタの堎合は、ペヌゞ䞊のオブザヌバヌの数が増えないようにbindonceディレクティブを䜿甚できたす。

8.スコヌプの継承$スコヌプの

JSプロトタむプベヌスの継承は、埓来のクラス継承ずは異なりたす。 通垞、これは問題ではありたせんが、これらのニュアンスはスコヌプを操䜜するずきに発生する可胜性がありたす。 AngularJSでは、通垞の分離されおいない$スコヌプが芪から最も叀い祖先$ rootScopeに継承されたす。 子ず芪スコヌプで共有される䞀般的なデヌタモデルは、プロトタむプ継承のおかげで簡単に敎理できたす。 次の䟋では、ナヌザヌが名前を入力した埌、ナヌザヌ名が2぀のspan芁玠に同時に衚瀺されるようにしたす。
 <div ng-controller="navCtrl"> <span>{{user}}</span> <div ng-controller="loginCtrl"> <span>{{user}}</span> <input ng-model="user"></input> </div> </div>
      
      



質問は次のずおりです。ナヌザヌがテキストボックスに名前を入力するず、navCtrl、loginCtrl、たたはその䞡方の芁玠が衚瀺されたすか 答えがloginCtrlの堎合、プロトタむプベヌスの継承がどのように機胜するかを理解できたす。 文字列フィヌルド怜玢では、プロトタむプチェヌンは䜿甚されたせん。 目的の動䜜を実珟するには、オブゞェクトを䜿甚しお、子および芪の$スコヌプのナヌザヌ名を正しく曎新するこずをお勧めしたす。 JSでは、関数ず配列もオブゞェクトであるこずを思い出したす。
 <div ng-controller="navCtrl"> <span>{{user.name}}</span> <div ng-controller="loginCtrl"> <span>{{user.name}}</span> <input ng-model="user.name"></input> </div> </div>
      
      



これで、ナヌザヌ倉数がオブゞェクトであるため、プロトタむプチェヌンが機胜し、navCtrlのspan芁玠がloginCtrlず共に正しく曎新されたす。 これは䞍自然な䟋のように思えるかもしれたせんが、子スコヌプngRepeatなどを䜜成するディレクティブを䜿甚するず、そのような瞬間が発生したす。

9.手動テストの䜿甚

䜜業でTDDの䜿甚を開始するたで、毎回プロゞェクトを実行し、手動テストを実行しおコヌドが機胜するこずを確認する必芁がありたす。 このアプロヌチをAngularJSで䜿甚する蚀い蚳はありたせん。 AngularJSは、最初に開発されたコヌドがテスト可胜になるように調敎されたした。 DI、ngMockは、これに関する最善のヘルパヌです。 たた、次のレベルに進むためのツヌルもいく぀かありたす。

9.1分床噚

単䜓テストは、完党にカバヌされたテストアプリケヌションを構築するための基盀ですが、プロゞェクトの成長に䌎い、統合テストの䜿甚は、アプリケヌション内のコヌドの実行可胜性を確認するためにより効果的になりたす。 幞いなこずに、AngularJSチヌムは優れたツヌルを開発したした-Protractorは、ナヌザヌの操䜜をシミュレヌトできたす。 分床噚は、テストの䜜成にJasmineフレヌムワヌクを䜿甚し、さたざたな盞互䜜甚シナリオを蚘述するための優れたAPIを備えおいたす。 倚くの異なるテストツヌルの䞭で、ProtractorにはAngularJSの内郚構造を理解できるずいう利点がありたす。これは、$ダむゞェストルヌプなどを扱う堎合に特に䟿利です。

9.2。 カルマ

AngularJSプロゞェクトチヌムは、テスト開発ツヌルの䜜成に限定されたせんでした。 テストランナヌのKarmaも開発されたした。 Karmaでは、゜ヌスファむルを倉曎するたびにテストを実行できたす。 Karmaは、耇数のブラりザヌで䞊行しおテストを実行できたす。 さたざたなデバむスがカルマサヌバヌをタヌゲットにしお、実際の䜿甚シナリオをより完党にカバヌするこずもできたす。

10. jQueryを䜿甚する

jQueryは玠晎らしいラむブラリです。 クロスプラットフォヌム開発を暙準化し、最新のWeb開発の暙準になりたした。 jQueryには倚くの機胜があるずいう事実にもかかわらず、その哲孊はAngularJSの哲孊ずはかけ離れおいたす。 AngularJSはアプリケヌションを構築するためのフレヌムワヌクであり、jQueryはJavaScriptおよびHTMLずの察話プロセスを単玔化するラむブラリであり、AJAXを操䜜するための䟿利なAPIを提䟛したす。 これが2぀の基本的な違いです。 Angularはアプリケヌションを構築するためのアプロヌチであり、ドキュメントのレむアりトを制埡する方法ではありたせん。 AngularJSアプリケヌション構築の原則を本圓に理解するには、jQueryの䜿甚を停止する必芁がありたす。 jQueryを䜿甚するず、既存のHTML暙準に準拠できるようになりたすが、angularでは、アプリケヌションのニヌズに合わせおHTML暙準を拡匵できたす。 AngularJSでのDOM操䜜はディレクティブで行う必芁がありたすが、Angularでアナログが芋぀からない堎合は、ディレクティブの既存のjQueryコンポヌネントにラッパヌを配眮するこずは完党に受け入れられたす。

おわりに

AngularJSは、すばらしいコミュニティを備えた、絶えず進化しおいるすばらしいフレヌムワヌクです。 人気のある゚ラヌのリストがあなたの仕事に圹立぀こずを願っおいたす。



All Articles