AngularJS は、Googleによって開発されたJavaScript MVCフレームワークであり、適切に構造化され、テストが容易で、保守が容易なフロントエンドアプリケーションを構築できます。
AngularJSをまだ試したことがない場合は、見逃していることになります。このフレームワークは、緊密に統合されたツールセットで構成されており、コードを減らして柔軟性を高めながら、適切に構造化された豊富なクライアント側アプリケーションをモジュール方式で構築できます。
AngularJSは、提供することでHTMLを拡張します ディレクティブ マークアップに機能を追加し、強力な動的テンプレートを作成できるようにします。独自のディレクティブを作成して、ニーズを満たす再利用可能なコンポーネントを作成し、すべてのDOM操作ロジックを抽象化することもできます。
また、双方向のデータバインディングを実装し、HTML(ビュー)をJavaScriptオブジェクト(モデル)にシームレスに接続します。簡単に言うと、これは、モデルの更新がDOM操作やイベント処理(jQueryなど)を必要とせずに、すぐにビューに反映されることを意味します。
Angularは、XHRに加えて、コードを劇的に簡素化し、API呼び出しを再利用可能なサービスに抽象化できるサービスを提供します。これにより、モデルとビジネスロジックをフロントエンドに移動し、バックエンドに依存しないWebアプリを構築できます。最後に、サーバー通信に関する柔軟性があるAngularが大好きです。ほとんどのJavaScriptMVCフレームワークと同様に、RESTful Web APIを介してアプリを提供できる限り、サーバー側のテクノロジーを使用できます。しかし、Angularはサービスも提供しています 上に コードを劇的に簡素化し、API呼び出しを再利用可能なサービスに抽象化できるXHRの機能。その結果、モデルとビジネスロジックをフロントエンドに移動し、バックエンドに依存しないWebアプリを構築できます。この投稿では、それを1ステップずつ実行します。
まず、作成するアプリの性質を決定しましょう。このガイドでは、バックエンドにあまり時間をかけたくないので、スポーツフィードアプリのように、インターネットで簡単に取得できるデータに基づいて何かを作成します。
私はたまたまモーターレースとフォーミュラ1の大ファンなので、オートスポーツAPIサービスを使用してバックエンドとして機能します。幸いなことに、 エルガスト 私たちにぴったりの無料のモータースポーツAPIを提供してくれます。
構築するもののスニークピークについては、 ライブデモ 。デモを美しくし、Angularテンプレートを披露するために、からBootstrapテーマを適用しました。 WrapBootstrap 、ただし、この記事はCSSに関するものではないため、例から抽象化して省略します。
ボイラープレートを使用して、サンプルアプリをキックスタートしましょう。私はお勧めします 角のある種子 プロジェクトは、ブートストラップのための優れたスケルトンを提供するだけでなく、ユニットテストの基礎を設定します。 カルマ そして ジャスミン (このデモではテストを行わないので、とりあえずそのようなものは脇に置いておきます。を参照してください。 パート2 ユニットおよびエンドツーエンドのテスト用にプロジェクトを設定する方法の詳細については、このチュートリアルのを参照してください)。
編集(2014年5月): このチュートリアルを書いたので、 角のある種子 プロジェクトはいくつかの大きな変更を経ました(の追加を含む バウアー パッケージマネージャーとして)。プロジェクトの展開方法について疑問がある場合は、プロジェクトの最初のセクションをざっと見てください。 リファレンスガイド 。に パート2 このチュートリアルの、 バウアー 、他のツールの中でも、より詳細に説明されています。
OK、リポジトリのクローンを作成して依存関係をインストールしたので、アプリのスケルトンは次のようになります。
これでコーディングを開始できます。レーシングチャンピオンシップのスポーツフィードを作成しようとしているので、最も関連性の高いビューから始めましょう。 チャンピオンシップテーブル 。
勘定科目表の設定方法
スコープ内にドライバーリストがすでに定義されており(私と一緒に-そこに着きます)、CSSを無視すると(読みやすくするため)、HTMLは次のようになります。
Drivers Championship Standings {{$index + 1}}
{{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}}
このテンプレートで最初に気付くのは、変数値を返すための式(“ {{“ and“}}”)の使用です。 AngularJS開発では 、式を使用すると、目的の値を返すために計算を実行できます。有効な式は次のとおりです。
{{ 1 + 1 }}
{ 946757880 }
{{ user.name }}
事実上、式はJavaScriptのようなスニペットです。ただし、非常に強力であるにもかかわらず、式を使用して高レベルのロジックを実装するべきではありません。そのために、ディレクティブを使用します。
次に気付くのは、通常のマークアップでは見られないng-attributes
の存在です。それらはディレクティブです。
大まかに言うと、ディレクティブは、特定の動作をDOM要素にアタッチする(または変換する、置き換えるなど)ようにAngularJSに指示するマーカー(属性、タグ、クラス名など)です。すでに見たものを見てみましょう:
ng-app
ディレクティブは、スコープを定義するアプリのブートストラップを担当します。 AngularJSでは、同じページ内に複数のアプリを含めることができるため、このディレクティブは、個別のアプリが開始および終了する場所を定義します。
ng-controller
ディレクティブは、ビューを担当するコントローラーを定義します。この場合、ドライバーのリスト(driversController
)を提供するdriversList
を示します。
ng-repeat
ディレクティブは最も一般的に使用されるものの1つであり、コレクションをループするときにテンプレートスコープを定義するのに役立ちます。上記の例では、driversList
内の各ドライバーのテーブル内の行を複製します。
もちろん、コントローラーなしではビューを使用することはできません。追加しましょうdriversController
私たちのcontrollers.jsに:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope) { $scope.driversList = [ { Driver: { givenName: 'Sebastian', familyName: 'Vettel' }, points: 322, nationality: 'German', Constructors: [ {name: 'Red Bull'} ] }, { Driver: { givenName: 'Fernando', familyName: 'Alonso' }, points: 207, nationality: 'Spanish', Constructors: [ {name: 'Ferrari'} ] } ]; });
$scope
にお気づきかもしれませんパラメータとしてコントローラに渡す変数。 $scope
変数は、コントローラーとビューをリンクすることになっています。特に、テンプレート内で使用されるすべてのデータを保持します。追加したもの(上記の例のdriversList
など)はすべて、ビューから直接アクセスできます。とりあえず、ダミー(静的)データ配列を操作してみましょう。これは後でAPIサービスに置き換えます。
次に、これをapp.jsに追加します。
angular.module('F1FeederApp', [ 'F1FeederApp.controllers' ]);
このコード行を使用して、実際にアプリを初期化し、アプリが依存するモジュールを登録します。後でそのファイル(app.js
)に戻ります。
c法人とs法人の違い
それでは、すべてをindex.html
にまとめましょう。
F-1 Feeder Drivers Championship Standings {{$index + 1}}
{{driver.Driver.givenName}} {{driver.Driver.familyName}} {{driver.Constructors[0].name}} {{driver.points}}
Moduloの小さな間違い、アプリを起動して(静的な)ドライバーのリストを確認できるようになりました。
注:アプリのデバッグや、ブラウザー内でのモデルとスコープの視覚化についてサポートが必要な場合は、すばらしいものをご覧になることをお勧めします。 バタラン Chrome用のプラグイン。
コントローラーのデータをビューに表示する方法はすでにわかっているので、RESTfulサーバーから実際にライブデータをフェッチするときが来ました。
HTTPサーバーとの通信を容易にするために、AngularJSは$http
を提供しますおよび$resource
サービス。前者は上の層にすぎません XMLHttpRequest または JSONP 、後者はより高いレベルの抽象化を提供します。 $http
を使用します。
コントローラからサーバーAPI呼び出しを抽象化するために、データをフェッチして$http
のラッパーとして機能する独自のカスタムサービスを作成しましょう。これをservices.js
に追加することで:
angular.module('F1FeederApp.services', []). factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
最初の2行で、新しいモジュール(F1FeederApp.services
)を作成し、そのモジュール内にサービスを登録します(ergastAPIservice
)。 $http
を渡すことに注意してくださいそのサービスへのパラメータとして。これはAngularの 依存性注入 新しいサービスに必要なエンジン(または に依存します )$http
サービス。
同様に、新しいモジュールをアプリに含めるようにAngularに指示する必要があります。 app.js
で登録し、既存のコードを次のように置き換えます。
angular.module('F1FeederApp', [ 'F1FeederApp.controllers', 'F1FeederApp.services' ]);
今、私たちがする必要があるのは私たちのcontroller.js
を微調整することです少し、ergastAPIservice
を含めます依存関係として、そして私たちは行ってもいいでしょう:
angular.module('F1FeederApp.controllers', []). controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; ergastAPIservice.getDrivers().success(function (response) { //Dig into the responde to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); });
次に、アプリをリロードして結果を確認します。テンプレートに変更を加えていないことに注意してください。ただし、nameFilter
を追加しました。私たちのスコープに可変。その変数を使用してみましょう。
すごい!機能的なコントローラーがあります。ただし、ドライバーのリストのみが表示されます。リストをフィルタリングする簡単なテキスト検索入力を実装して、いくつかの機能を追加しましょう。タグのすぐ下のindex.html
に次の行を追加しましょう。
ng-model
現在、 この行は この時点で、双方向のデータバインディングが開始されます。検索フィールドに値が入力されるたびに、Angularはすぐに アプリをリロードして、検索バーを確認してください。 このフィルターは、使用していない属性も含め、モデルのすべての属性でキーワードを検索することに注意してください。 ここで、 アプリをもう一度リロードすると、名前で検索できるようになります。 次の目標は、各ドライバーをクリックしてそのキャリアの詳細を確認できるドライバー詳細ページを作成することです。 まず、 その変更に伴い、 AngularJSを使用すると、ルートを特定のコントローラーとビューにバインドできます。 ただし、最初に、これらの部分ビューをレンダリングする場所をAngularに指示する必要があります。そのために、 これで、アプリのルートをナビゲートするたびに、Angularは関連するビューを読み込み、タグの代わりにレンダリングします。 最後に、詳細ページに何を表示するかを決定しましょう。ドライバーに関連するすべての事実(出生、国籍など)の要約と、最近の結果を含む表はどうですか?そのために、 今回は、特定のドライバーのみに関連する情報を取得できるように、ドライバーのIDをサービスに提供します。ここで、 ここで注意すべき重要なことは、 スコープ内にデータが含まれるようになったので、残りの部分ビューのみが必要です。 たくさんのCSSを追加して、ページをレンダリングします。あなたはこのようなものになるはずです: これでアプリを起動する準備が整い、両方のルートが希望どおりに機能していることを確認できます。 編集(2014年5月): このチュートリアルで作成したコードのダウンロード可能なバージョンについて、多くのリクエストを受け取りました。したがって、リリースすることにしました ここに (CSSを取り除いた)。しかし、私は本当にします ない このガイドには、自分の手で同じアプリケーションを作成するために必要なすべてのステップが含まれているため、ダウンロードすることをお勧めします。これは、はるかに便利で効果的な学習演習になります。 チュートリアルのこの時点で、簡単なアプリ(F1フィーダーなど)を作成するために必要なすべてのことを説明しました。ライブデモの残りの各ページ(コンストラクターチャンピオンシップテーブル、チームの詳細、カレンダーなど)は、ここで確認したものと同じ基本構造と概念を共有しています。 最後に、Angularは非常に強力なフレームワークであり、提供するすべての点で表面をほとんど傷つけていないことを忘れないでください。に パート2 このチュートリアルでは、AngularがピアフロントエンドMVCフレームワークの中で際立っている理由の例を示します:テスト容易性。単体テストを作成して実行するプロセスを カルマ 、との継続的インテグレーションを実現 ヨーマン 、 接地 、および バウアー 、およびこの素晴らしいフロントエンドフレームワークの他の長所。 AngularJSは、Googleによって開発されたJavaScript MVCフレームワークであり、適切に構造化され、テストが容易で、保守が容易なフロントエンドアプリケーションを構築できます。 AngularJSは、マークアップに機能を追加し、強力な動的テンプレートを作成できるようにするディレクティブを提供することでHTMLを拡張します。また、独自のディレクティブを作成し、ニーズを満たす再利用可能なコンポーネントを作成し、すべてのDOM操作ロジックを抽象化することもできます。$scope.nameFilter
を利用しています指令。このディレクティブは、テキストフィールドをng-repeat
にバインドします。変数であり、その値が常に入力値で最新であることを確認します。それでは、もう一度index.htmlにアクセスして、 を含む行を少し調整してみましょう。指令: ng-repeat
driversList
を示していますつまり、データを出力する前に、nameFilter
配列は、$scope.nameFilter
に格納されている値でフィルタリングする必要があります。nameFilter
を確認します。関連付けたものが新しい値で更新されます。バインディングは双方向で機能するため、ng-repeat
の瞬間値が更新され、それに関連付けられた2番目のディレクティブ(つまり、Driver.givenName
)も新しい値を取得し、ビューがすぐに更新されます。Driver.familyName
でのみフィルタリングしたいとします。およびdriversController
:まず、$scope.driversList = [];
のすぐ下にある$scope.searchFilter = function (driver) ;
に追加します。ライン:index.html
ng-repeat
に戻り、 を含む行を更新します。指令: $routeProvider
ルート
app.js
を含めましょうこれらのさまざまな問題に対処するのに役立つサービス(app.js
内) アプリケーションルート 。次に、そのような2つのルートを追加します。1つはチャンピオンシップテーブル用で、もう1つはドライバーの詳細用です。これが私たちの新しいangular.module('F1FeederApp', [ 'F1FeederApp.services', 'F1FeederApp.controllers', 'ngRoute' ]). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/drivers', {templateUrl: 'partials/drivers.html', controller: 'driversController'}). when('/drivers/:id', {templateUrl: 'partials/driver.html', controller: 'driverController'}). otherwise({redirectTo: '/drivers'}); }]);
です:http://domain/#/drivers
driversController
に移動しますpartials/drivers.html
をロードしますng-view
でレンダリングする部分ビューを探します。ちょっと待って!まだ部分的な見方はありませんよね?それらも作成する必要があります。部分ビュー
index.html
を使用しますディレクティブ、 F-1 Feeder
を変更以下をミラーリングします。partials/drivers.html
という名前のファイルを作成するだけです。そこにチャンピオンシップテーブルのHTMLを配置します。また、この機会を利用して、ドライバー名をドライバー詳細ルートにリンクします。
Drivers Championship Standings {{$index + 1}} {{driver.Driver.givenName}} {{driver.Driver.familyName}}
{{driver.Constructors[0].name}} {{driver.points}} services.js
angular.module('F1FeederApp.services', []) .factory('ergastAPIservice', function($http) { var ergastAPI = {}; ergastAPI.getDrivers = function() { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverDetails = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/driverStandings.json?callback=JSON_CALLBACK' }); } ergastAPI.getDriverRaces = function(id) { return $http({ method: 'JSONP', url: 'http://ergast.com/api/f1/2013/drivers/'+ id +'/results.json?callback=JSON_CALLBACK' }); } return ergastAPI; });
に追加します。controllers.js
angular.module('F1FeederApp.controllers', []). /* Drivers controller */ controller('driversController', function($scope, ergastAPIservice) { $scope.nameFilter = null; $scope.driversList = []; $scope.searchFilter = function (driver) re.test(driver.Driver.familyName); ; ergastAPIservice.getDrivers().success(function (response) { //Digging into the response to get the relevant data $scope.driversList = response.MRData.StandingsTable.StandingsLists[0].DriverStandings; }); }). /* Driver controller */ controller('driverController', function($scope, $routeParams, ergastAPIservice) { $scope.id = $routeParams.id; $scope.races = []; $scope.driver = null; ergastAPIservice.getDriverDetails($scope.id).success(function (response) { $scope.driver = response.MRData.StandingsTable.StandingsLists[0].DriverStandings[0]; }); ergastAPIservice.getDriverRaces($scope.id).success(function (response) { $scope.races = response.MRData.RaceTable.Races; }); });
を変更します。$routeParams
:id
を注入したことです。ドライバーコントローラーへのサービス。このサービスにより、$routeParams.id
を使用してURLパラメーター(この場合はpartials/driver.html
)にアクセスできるようになります。 <- Back to drivers list
という名前のファイルを作成しましょうそして追加:
{{driver.Driver.givenName}} {{driver.Driver.familyName}} Country: {{driver.Driver.nationality}}
Team: {{driver.Constructors[0].name}}
Birth: {{driver.Driver.dateOfBirth}}
Biography
Formula 1 2013 Results Round Grand Prix Team Grid Race {{race.round}} {{race.raceName}}
{{race.Results[0].Constructor.name}} {{race.Results[0].grid}} {{race.Results[0].position}} ng-show
true
を配置していることに注意してください有効に使用するための指示。このディレクティブは、提供された式がfalse
である場合にのみHTML要素を表示します。 (つまり、null
でもindex.html
でもありません)。この場合、アバターは、コントローラーによってドライバーオブジェクトがスコープにロードされた後にのみ表示されます。仕上げ
|_+_|
に静的メニューを追加することもできますユーザーのナビゲーション機能を向上させるため。可能性は無限大。 結論
技術設計書の書き方
基本を理解する
AngularJSとは何ですか?
なぜAngularJSなのか?