AngularJSチュートリアル

14960 ワード

本文はここから翻訳された.
翻訳の過程で翻訳者本人の理解を加え、適切なスクリーニングを行った.
 
概要
簡単なメールアプリケーションを作成し、コアのAngularJS概念を学習します.このチュートリアルの学習を終了すると、メールのトピックに基づいてメールを検索したり、メールを読んだり削除したりする(架空の)メールアプリケーションが表示されます.
 
学習の前提条件:
  • jQueryを使用して簡単なJavaScriptアプリケーション
  • を作成します.
  • 簡単なHTTPサーバー(python-m SimpleHTTPServerなど)
  • を起動する方法を知っています.
  • Githubからプロジェクト
  • がクローンされます.
    対象
  • 単ページアプリケーション(SPA)
  • クライアントMVCモード
  • 双方向データバインディング
  • ルーティングとテンプレート
  • AngularJS構築ブロック:ディレクティブラベル(Directives)、ファクトリ(Factories)、およびコントローラ(Controllers)
  • クライアントMVC
  • モデル(Model):データと言える;アプリケーションのビジネス情報;
  • ビュー(View):HTMLとデータの表示.ユーザーが見たインタフェースとインタラクティブなインタフェースです.
  • コントローラ(Controller):アプリケーション内のすべての異なるモジュールを協働させるコネクタ.

  • AngularJSの使用開始
    ページにAngularJSを導入する
    HTMLページの下部終了ラベルの前にAngularJSを導入する.jsファイル.
    <html>
        <head>
        </head>
        <body>
            <div></div>
            <script src="lib/jquery-v1.11.1.js"></script>
            <script src="lib/angular-v1.2.22.js"></script>
        </body>
    </html>
    

     
    Angular自身には「jQLite」というものが内蔵されており、jQueryのようなマイクロライブラリです.jQLiteは非常に軽量なライブラリなので、必要な強力なjQueryメソッドはありません.ここでjQueryを導入するのは、jQueryライブラリに依存するプラグインが後で導入される可能性があるためです.
     
    スコープとディレクティブラベルの設定
    Angularの非常に基礎的な概念の一つは役割ドメイン(scopes)である.ScopesはあなたのModels(つまりあなたのデータ)を保存しています.コントローラ(Controllers)と協力し、ビュー(Views)に必要なすべてを提供します.Angularのscopes概念は一般的なJavaScriptの役割ドメイン(scope)概念とよく似ている.
     
    最初のステップは、Angularアプリケーションが機能する範囲を識別するアプリケーション全体の役割ドメインを設定する必要があります.通常、ラベルでng-appプロパティで設定します.
    <html ng-app="myApp">
        <head></head>
        <body></body>
    </html>
    

     
    もう1つのscopeに関連する命令はng-controllerであり,コントローラの役割ドメイン範囲を決定する.1つのアプリケーションに複数のコントローラを含めることができます.各コントローラには、独自の役割ドメイン範囲があります.
    <div ng-controller="InboxCtrl">
        <!-- inside InboxCtrl scope -->
    </div>
    

     
    ng-appとng-controllerはいずれもAngular命令ラベルである.AngularコマンドラベルはHTMLへの拡張と見なすことができる.
     
    あなたの最初のコントローラ:簡単な例です
    私たちが学んだことを実践に応用します
    1空のHTMLドキュメントを作成する
    2 AngularとjQueryファイルの導入
    <script src="lib/jquery-v1.11.1.js"></script>
    <script src="lib/angular-v1.2.22.js"><script>
    

     
    3タブにng-app="myApp"を追加
    4 bodyでコントローラの例を作成する
    <div ng-controller="TestCtrl"><h1></h1>
       <input type="text" ng-model="title">
    </div>
    

    ng-model=「title」の意味は後述する.
    5参照されたライブラリファイルの後にスクリプトが埋め込まれているJavaScriptスクリプトを作成します.
    <script>
       function TestCtrl($scope) {
          $scope.title = 'Write a title here...';
       };
    </script>
    

    関数の名前はng-controllerの値と同じであることがわかりましたか?Angularは、JavaScriptでコントローラとして同じ名前の関数を探します.
     
    完全なコードは次のとおりです.
    <!doctype html>
    <html ng-app>
      <head>
        <title>Sample AngularJS Controller</title>
      </head>
      <body>
        <div ng-controller="TestCtrl">
            <h1></h1>
            <input type="text" ng-model="title">
        </div>
    
        <script src="lib/jquery-v1.11.1.js"></script>
        <script src="lib/angular-v1.2.22.js"></script>
    
        <script>
          function TestCtrl($scope) {
            $scope.title = 'Write a title here...';
          };
        </script>
      </body>
    </html>

     
    ngViewとルーティング(Routes)
    URLを役割ドメインに関連付ける
    もう1つの重要な構築ブロックはng-viewコマンドラベルであり、アプリケーションのURLを役割ドメインに関連付けることができる.
    <html ng-app="myApp">
        <head>
        </head>
        <body>
            <div ng-view></div>
        </body>
    </html>

     
    ここのng-viewタグは、ユーザーがアクセスしたURLに基づいてAngularが挿入したいHTMLを伝えることができます.
     
    モジュール(Modules)
    angular.module()
    各アプリケーションにはモジュールが必要であり、Angularはangularを通過する.module()は、モジュールネーミングスペースの機能を提供します.この方法は、モジュールを設定したり、モジュールを取得したりすることができます.重要なのは、どのように使用するかによって異なります.次のような新しいモジュールを作成(設定)します.
    angular.module('myApp', []);

     
    コントローラ、factories、filtersなどを登録するためのモジュールの参照を取得します.後ろの配列を使わずにモジュールの名前だけを通過することができます.
    angular.module('myApp');

     
    ルーティング(Routing)と依存注入(Dependency Injection)
    ルート
    次に、ルーティングを構成し、アプリケーションがアクセスしたURLに基づいてどのビューをロードするかを決定できるようにします.
    RouteProvider
    Angular 1.2.0以降、コアのAngularには$routeProviderが含まれていないため、独立したモジュールとして導入する必要があります(angular-route.js).
    <body>
        <!-- ... -->
        <!-- Extra routing library -->
        <script src="lib/angular-route-v1.2.22.js"></script>
    </body>
    

     
    このファイルは、ngRouteというモジュールを提供しています.独自のモジュール定義では、依存として導入する必要があります.
    var app = angular.module('app', [
       'ngRoute'
    ]);

     
    構成フェーズ
    Angularの各モジュールは1つを有する.config()メソッドは、多くの他の関数が実行される前に呼び出されるコールバック関数を入力します.この場所で私たちのルートを配置します.
    app.config(function () {/*...*/});

     
    依存注入
    configコールバック関数では,ルートを構成するために$routeProviderが必要であり,簡単に$routeProviderをconfig関数のパラメータとして伝達し,残りのことはAngularに任せることができる.
    app.config(function ($routeProvider) {
       /* Now we can use the routeProvider! :D */
    });

     
    ルーティングの設定
    app.config(function ($routeProvider) {
       $routeProvider
          .when('/inbox', {
             templateUrl: 'views/inbox.html',
             controller: 'InboxCtrl',
             controllerAs: 'inbox'
          })
          .when('/inbox/email/:id', {
             templateUrl: 'views/email.html',
             controller: 'EmailCtrl',
             controllerAs: 'email'
          })
          .otherwise({
             redirectTo: '/inbox'
          });
    });

     
    コントローラ(Controllers)
    モデルとビューの接続
    良いコントローラには、できるだけ少ない論理しか含まれておらず、モデルをビューにバインドする(ビューを初期化する);ビューにヘルプ関数を追加します.
    app.controller('InboxCtrl', function () {
       // Model and View bindings
       // Small helper function not needed anywhere else
    });

     
    各コントローラは$scopeにアクセスできます.$scopeでプロパティとメソッドをビューに追加できます.
    app.controller('InboxCtrl', function ($scope) {
       // initialize the title property to an array for the view to use
       $scope.title = "This is a title";
    });

     
    ラベルには次のように対応できます.
    <div ng-controller="InboxCtrl">
       {{ title }}
    </div>
    

     
    工場(Factories)
    工場では、HTTPを介してサービス側と対話するためによく使用されます.
    angularを通ることができます.factory()メソッドは、次のようなファクトリを作成します.
    app.factory('ExampleFactory', function ExampleFactory($rootScope, $http, $location) {
       return function myReusableFunction() {
          // do something fancy
       };
    });

     
    このアプリケーションでは、メール情報を取得する必要があり、実装する方法を作成することができます.Angularは$httpサービスを使用してサービス側と対話するため、それを導入する必要があります.
    app.factory('InboxFactory', function InboxFactory ($http) {
       var exports = {};
    
       exports.getMessages = function () {
          return $http.get('json/emails.json')
             .error(function (data) {
                console.log('There was an error!', data);
          });
       };
    
       return exports;
    });

     
    関連工場とコントローラ
    app.controller('InboxCtrl', function($scope, InboxFactory) {
       InboxFactory.getMessages()
          .success(function(jsonData, statusCode) {
             console.log('The request was successful!', statusCode, jsonData);
             // Now add the Email messages to the controller's scope
             $scope.emails = jsonData;
       });
    });

     
    テンプレート(Templating)
    ビューレンダリング
    <!-- JavaScript inside expression -->
    <h1>{{ [ firstName, lastName ].join(" ") }}</h1>
    <!-- currency filter applied to a multiplication of 2 numbers -->
    <div class="total-info">{{ cost * quantity | currency }}</div>
    <!-- Using a ternary expression inside the expression -->
    <div class="budget">{{ ( total > budget ) ? "Too Expensive" : "You can buy it!" }}</div>
    

     
    ディレクティブラベルの概要
    カスタムHTMLラベル
    コマンドラベルはAngularが提供するカスタムHTMLラベルで、データ、テンプレート、動作をカプセル化するために再利用可能な方法を提供します.
    ビューでは、次のラベルが表示されることがあります.
    <div id="someview">
       {{ data.scopePropertyAsUsual }}
       <my-custom-element></my-custom-element>
    </div>
    

     
    上のラベルは、定義したラベルテンプレートと論理に置き換えられます.簡単なコマンドラベル構造の例を次に示します.
    app.directive('myCustomElement', function myCustomElement() {
       return {
          restrict: 'EA',
          replace: true,
          scope: true,
          template: [
             "<div>",
             "	<h1>My Custom Element's Heading</h1>",
             "	<p>Some content here!</p>",
             "	<pre>{{ ctrl.expression | json }}</pre>,"
             "</div>"
          ].join(""),
          controllerAs: 'ctrl',
          controller: function ($scope) {
             this.expression = {
                property: "Example"
             }
          },
          link: function (scope, element, attrs) {}
       }
    });

     
    工場と指令の協同作業
    angular.module('EmailApp')
       .factory('InboxFactory', function InboxFactory ($q, $http, $location) {
          'use strict';
          var exports = {};
    
          exports.messages = [];
    
          exports.goToMessage = function(id) {
             if ( angular.isNumber(id) ) {
                // $location.path('inbox/email/' + id)
             }
          }
    
          exports.deleteMessage = function (id, index) {
             this.messages.splice(index, 1);
          }
    
          exports.getMessages = function () {
             var deferred = $q.defer();
             return $http.get('json/emails.json')
                .success(function (data) {
                   exports.messages = data;
                   deferred.resolve(data);
                })
                .error(function (data) {
                   deferred.reject(data);
                });
             return deferred.promise;
          };
    
          return exports;
       });

     
    app.directive('inbox', function () {
       return {
          restrict: 'E',
          replace: true,
          scope: true,
          templateUrl: "js/directives/inbox.tmpl.html",
          controllerAs: 'inbox',
          controller: function (InboxFactory) {
             this.messages = [];
             this.goToMessage = function (id) {
                InboxFactory.goToMessage(id);
             };
             this.deleteMessage = function (id, index) {
                InboxFactory.deleteMessage(id, index);
             };
             InboxFactory.getMessages()
                .then( angular.bind( this, function then() {
                   this.messages = InboxFactory.messages;
                })	);
          },
          link: function (scope, element, attrs, ctrl) {
             /*
             by convention we do not $ prefix arguments to the link function
             this is to be explicit that they have a fixed order
             */
          }
       }
    });

     
    上記のコマンドラベルに使用される完全なHTMLテンプレート:
     
    <div class="inbox">
      <div class="inbox__count">
        You have {{ inbox.messages.length && inbox.messages.length || 'no' }} messages
      </div>
      <div ng-hide="!inbox.messages.length">
        <input type="text" class="inbox__search" 
          ng-model="inbox.search" 
          placeholder="Search by 'from', e.g. TicketMaster">
      </div>
      <ul class="inbox__list">
        <li ng-show="!inbox.messages.length">
          No messages! Try sending one to a friend.
        </li>
        <li ng-repeat="message in inbox.messages | filter:{ from: inbox.search }">
          <div class="inbox__list-info">
            <p class="inbox__list-from"> from: {{ message.from }} </p>
            <p class="inbox__list-date"> {{ message.date | date: 'dd/MM/yyyy' }} </p>
            <p class="inbox__list-subject"> {{ message.subject }} </p>
          </div>
          <div class="inbox__list-actions">
            <a href="#" ng-click="inbox.goToMessage(message.id);">
              Read
            </a>
            <a href="" ng-click="inbox.deleteMessage(id, $index);">
              Delete
            </a>
          </div>
        </li>
      </ul>
    </div>
    

     
    組み込み命令ラベル
    ng-show, ng-repeat, ng-click
     
    <ul>
       <li ng-repeat="item in items">
          {{ item.name }}
       </li>
    </ul>
    

     
     
    <li ng-repeat="message in inbox.messages | filter:{ from: inbox.search }">

     
     
    <input type="text" class="inbox__search" placeholder="Search" ng-model="inbox.search">