ng-Controller を使用した AngularJS コントローラーの例

⚡ スマートサマリー

AngularJS のコントローラーは、画面のビジネス ロジックを保持します。スコープ オブジェクトを介してデータを受け取り、処理し、結果をビューに公開します。ping アプリケーションロジックを含まないプレゼンテーション用マークアップ。

  • 🎯 主な責任: コントローラはスコープオブジェクトを設定し、ビューにメソッドを公開しますが、DOMを操作することはありません。
  • 🔗 配線: ng-controllerディレクティブは、名前付きコントローラを要素にバインドし、その要素とその子要素にコントローラのスコープへのアクセス権限を与えます。
  • 🔁 双方向製本: ng-modelはフォームフィールドをスコーププロパティにリンクするため、ビューで編集するとコントローラーが更新され、その逆も同様です。
  • 🧩 メソッド: スコープにアタッチされた関数は、個別のロジックを分離し、ビュー式から直接呼び出すことができます。
  • 🏷️ controllerAs構文: コントローラーのエイリアスとバインディング this コントローラーが互いにネストされている場合の曖昧さを解消します。
  • 📁 分離: コントローラーを専用のapp.jsに移動することで、ビュー層とロジック層を独立させることができます。

ng-controllerを使用したAngularJSコントローラー

AngularJS のコントローラーとは何ですか?

A コントローラー AngularJSでは、コントローラーはビューからデータを受け取り、データを処理した後、そのデータをエンドユーザーに表示されるビューに送信します。コントローラーはコアとなるビジネスロジックを保持します。データモデルを使用し、必要な処理を実行し、その結果をビューに渡します。

⚠️ バージョンノート: AngularJS(1.xブランチ)は2021年12月31日にサポートが終了し、セキュリティパッチは提供されなくなりました。以下の概念はレガシーアプリケーションには引き続き適用されますが、最新のAngularでは、コントローラーではなくコンポーネントクラスが同じ役割を担います。

コントローラーとは何かを理解したとしても、一つ疑問が残ります。それは、コントローラーがビューとどのように通信するのかということです。次のセクションでは、その疑問に答えます。

Angularの観点から見たコントローラーの役割

以下は、AngularJSコントローラーの動作に関する簡単な定義です。

AngularJSコントローラーの働き
AngularJSコントローラーの働き
  • コントローラーの主な役割は、ビューに渡されるデータを制御することです。 スコープとビューは双方向通信を行います。
  • ビューのプロパティとイベントはスコープの関数を呼び出すことができます。以下のスニペットは、 関数($スコープ) コントローラーと内部関数で宣言され、 $scope.firstName (NAIST) と $scope.lastName 参加しました。 AngularJS変数として定義された関数はメソッドです。

AngularJSコントローラーの働き

  • データはコントローラからスコープへ渡され、その後スコープとビューの間でやり取りされる。
  • スコープは、モデルをビューに公開します。モデルは、スコープ上で定義されたメソッドを介して変更でき、これらのメソッドはビューからのイベントによってトリガーされます。
  • コントローラーはDOMの操作には使用すべきではありません。それは ディレクティブ.
  • コントローラーは機能に基づいて作成するのがベストプラクティスです。入力フォームにコントローラーが必要な場合は、「フォームコントローラー」という名前のコントローラーを作成してください。

仕組みを理解した上で、次のセクションでは空のページからコントローラーを構築します。

AngularJS で基本的なコントローラーを構築する方法

以下に、AngularJSでコントローラーを作成する手順を示します。

ステップ 1) 基本的な HTML ページを作成する

コントローラーを作成する前に、基本的な HTML ページを用意する必要があります。以下のスニペットは、「イベント登録」というタイトルのシンプルなページで、 Bootstrap そしてAngularJS。

AngularJS で基本コントローラーを構築する

  1. 参照 Bootstrap CSS スタイルシートは、 Bootstrap としょうかん。
  2. AngularJSライブラリへの参照です。ここから先、AngularJSで行われるすべての処理はこのファイルから解決されます。
  3. への参照 Bootstrap 特定のコントロールを応答可能にするライブラリ。

⚠️ 訂正: 元のコードは jQuery をロードし、AngularJS がそれに依存していると述べていましたが、そうではありません。AngularJS には jQuery API の組み込みサブセットである jqLit​​e が同梱されており、jQuery がロードされた場合にのみ完全な jQuery にアップグレードされます。 それ。参照は削除されました。

ステップ 2) ファイルとファイル構造を確認する

AngularJS で基本コントローラーを構築する

  1. ファイルは、一般的なウェブアプリケーションと同様に、スタイルシート用の「css」と、 Javaスクリプト ファイル。
  2. bootstrap.cssはcssフォルダ内にあり、サイトの外観と操作感を決定します。
  3. angular.js はメインライブラリで、AngularJS サイトからダウンロードされ、lib に格納されます。
  4. app.jsにはコントローラーのコードが含まれます。

ステップ 3) AngularJS コードを使用して出力を表示する

ここでの目標は、ブラウザでページを開いたときに、「AngularJS」という単語をプレーンテキストとして、またテキストボックス内にも表示することです。

AngularJS で基本コントローラーを構築する

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<h1> Guru99 Global Event</h1>

<div ng-app="DemoApp" ng-controller="DemoController">
Tutorial Name : <input type="text" ng-model="tutorialName"><br>
This tutorial is {{tutorialName}}
</div>

<script src="lib/angular.js"></script>
<script>
var app = angular.module('DemoApp', []);

app.controller('DemoController', ['$scope', function($scope) {
  $scope.tutorialName = "AngularJS";
}]);
</script>
</body>
</html>

Code 説明:

  1. ng-アプリ この要素は、AngularJS アプリケーションのルートであることを示します。 NG- これらは組み込みのディレクティブです。「DemoApp」はアプリケーションに付けられた名前です。
  2. div は ng-コントローラー 「DemoController」という名前が付けられており、その要素とその内部にあるすべての要素がコントローラースコープにアクセスできるようになります。
  3. ng-モデル モデルバインディングを作成し、チュートリアル名テキストボックスをスコーププロパティに紐付けます。 tutorialName.
  4. モジュール DemoApp が作成され、コントローラーは「AngularJS」というデフォルト値を割り当てます。 tutorialName.

⚠️ 修正を適用しました。 元の出品では chrset="UTF 8"これは有効な属性でも有効なエンコード名でもなく、AngularJS を 2 回ロードしました。1 回は CDN から、もう 1 回は lib/angular.jsライブラリを2回ロードすると、モジュールシステムが再登録され、予期しない動作が発生します。依存関係配列の注釈 ['$scope', function($scope){…}] また、これも追加されました。これがないと、ファイルがミニファイされた瞬間にコントローラーが壊れてしまいます。

出力:

AngularJS で基本コントローラーを構築する

なぜなら tutorialName 値「AngularJS」が割り当てられ、その値がテキストボックスとプレーンテキスト行に表示されます。デモンストレーションには単一のプロパティで十分ですが、実際のコントローラーは通常、動作も公開します。これについては次のセクションで説明します。

AngularJS コントローラーでメソッドを定義する方法

通常、ビジネスロジックを分離するために、コントローラに複数のメソッドを定義します。コントローラが2つの数値を加算して減算する必要がある場合trac2つの数値を扱う場合、それぞれの演算に対して1つのメソッドを作成します。

以下の例では、AngularJSコントローラー内に文字列を返すカスタムメソッドを定義しています。

AngularJS コントローラーでのメソッドの定義

<!-- The head and library references are unchanged from Step 3 -->
<div ng-app="DemoApp" ng-controller="DemoController">
Tutorial Name : <input type="text" ng-model="tutorialName"><br>
This tutorial is {{tName()}}
</div>

<script>
var app = angular.module('DemoApp', []);

app.controller('DemoController', ['$scope', function($scope) {
  $scope.tutorialName = "AngularJS";

  // A method on the scope, callable from the view as tName()
  $scope.tName = function() {
    return $scope.tutorialName;
  };
}]);
</script>

Code 説明:

  1. 関数はスコープオブジェクトにメンバーとして添付されます tName. 現在の値を返します tutorialName.
  2. ビューはメソッドを呼び出します {{tName()}}括弧は重要です。括弧がないと、式は関数の結果ではなく、関数自体を出力します。

⚠️ 訂正: 元の方法を読んでみると $scope.tName = function() { return $scope.tName; };その関数はチュートリアル名ではなく自身を返すため、ページにはテキストではなく関数本体が表示されました。現在は、 $scope.tutorialName.

出力:

AngularJS コントローラーでのメソッドの定義

これまではすべて1つのファイルにまとめられていましたが、本番環境のアプリケーションではコントローラーを別々に管理します。次のセクションでは、その方法を説明します。

ng-Controller を使用した AngularJS コントローラーの例

上記の「HelloWorld」の例では、すべての機能を1つのファイルにまとめていました。今度は、コントローラーのコードを別のファイルに移動しましょう。

ステップ1) app.jsファイルに、コントローラー用の以下のコードを追加してください。

ng-Controller を使用した AngularJS コントローラー

angular.module('app', [])
  .controller('HelloWorldCtrl', ['$scope', function($scope) {
    $scope.message = "Hello World";
  }]);

上記のコードは次のことを行います。

  1. コントローラを保持する「app」というモジュールを定義します。
  2. 「Hello World」というメッセージを表示する「HelloWorldCtrl」という名前のコントローラーを作成します。
  3. スコープオブジェクトを使用して、コントローラからビューに情報を渡します。この場合は、変数という名前です。 message.

ステップ2) Sample.html に、ng-controller ディレクティブとメンバー変数への参照を含む div を追加します。 messageコントローラーのソースコードが格納されているapp.jsを参照することを忘れないでください。

ng-Controller を使用した AngularJS コントローラー

<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="UTF-8">
<title>Event Registration</title>
<link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<h1> Guru99 Global Event</h1>
<div class="container">
<div ng-controller="HelloWorldCtrl">{{message}}</div>
</div>

<script src="lib/angular.js"></script>
<script src="app.js"></script>
</body>
</html>

⚠️ 訂正: app.jsを読み込む必要があります After angular.js を呼び出すので angular.moduleオリジナル版もライブラリを2回ロードし、同じ内容を保持していました。 chrset 打ち間違え。

出力:

ng-Controller を使用した AngularJS コントローラー

これまでの例はすべて、プロパティを直接読み書きしています $scope以下のセクションでは、AngularJSチームが推奨する代替案について説明します。

AngularJSでcontrollerAs構文を使用する方法

直接結合する $scope 機能しますが、コントローラーがネストされるとすぐに曖昧になります。次のようなビュー式 {{name}} どのコントローラーが所有しているか全く手がかりがない nameまた、子スコープは親スコープからプロトタイプ的に継承するため、継承されたプリミティブに書き込むネストされたコントローラは、暗黙のうちに独自のシャドウコピーを作成します。 controllerAs この構文は、各コントローラにエイリアスを与えることで、両方の問題を解消します。

ステップ1) ビューでコントローラーにエイリアスを設定する as キーワードを指定し、そのエイリアスをすべてのバインディングのプレフィックスとして追加します。

ステップ2) コントローラー内で、プロパティをアタッチします this むしろ $scope.

<div ng-controller="DemoController as demo">
Tutorial Name : <input type="text" ng-model="demo.tutorialName">
This tutorial is {{demo.tutorialName}}
</div>

<script>
app.controller('DemoController', function() {
  // 'vm' is captured so nested functions keep the right reference
  var vm = this;
  vm.tutorialName = "AngularJS";

  vm.tName = function() {
    return vm.tutorialName;
  };
});
</script>

3つの利点があります。バインディングは自己文書化されるようになります。 demo.tutorialName 所有者を指定します。ネストされたコントローラーは、親エイリアスが設定されているため、衝突しなくなります。 outer そして、偽名を付けられた子供 inner 両方とも暴露できる name値は、単純なプリミティブではなくオブジェクトを介してバインドされ、ping 子要素で行われた編集が親要素に反映されないという落とし穴。

💡 ヒント: キャプチャ this 変数に次のように vm コントローラーの先頭で。コールバック内で、 this 全く別のものを参照しており、キャプチャされた参照によってバインディングが正しく維持されます。

バインディングスタイルを選択することは一つの決定事項です。コントローラーに何を含めるべきかを決定することはまた別の決定事項であり、以下の比較はその境界線を明確に示しています。

AngularJSにおけるコントローラーとサービス

初心者は、本来サービスで処理すべき作業をコントローラーに詰め込みすぎてしまうことがよくあります。両者の違いは、ライフサイクルと再利用性にあります。コントローラーはビューが画面に表示されている間だけ存在しますが、サービスはアプリケーションのライフサイクル全体にわたって存在するシングルトンです。

側面 コントローラー サービス
生涯保証 景色とともに創造され、破壊される アプリケーション全体を単一のインスタンスで管理
目的 1つのビュー用のデータを準備する 共有ロジック、状態、およびサーバー呼び出し
再利用可能な いいえ、その景色に結びついています はい、どこにでも注射可能です
ビュー間で状態を保持する いいえ、ナビゲーション中に状態が失われます はい、状態は継続しています
典型的なコンテンツ スコープのプロパティとビューメソッド HTTP呼び出し、キャッシング、ビジネスルール

コントローラーはシンプルに保ちましょう。2つのコントローラーで同じロジックが必要な場合、またはビュー間のナビゲーション後も値が保持される必要がある場合は、その値をサービスに移動し、必要な場所にそのサービスを注入してください。実用的なテストとしては、現在の画面が閉じている状態でもコードが意味を成すかどうかを自問してみることです。答えが「はい」であれば、そのコードはサービスに記述するべきです。

よくあるご質問

はい。AngularJSは、ディレクティブを持つ要素ごとに個別のインスタンスとスコープを作成します。これらのインスタンスは状態を共有しないため、一方のインスタンスの変更はもう一方のインスタンスには反映されません。

コントローラーがビュー全体に属する場合、ルートで宣言します。 ルーティング現在のルートに関係なくページ内に表示されるコンポーネントには、ng-controllerを使用してください。両方を宣言すると、コントローラーが2回実行されるため、絶対に宣言しないでください。

配列アノテーションを使用し、関数の前に依存関係名を文字列として記述します。ミニファイアは関数の引数の名前を変更しますが、文字列リテラルの名前は変更しないため、インジェクターは引き続き$scopeとサービスを正しく解決します。

Yes. AI アシスタントは、画面の単純な記述からモジュール、コントローラ、スコープのバインディングを生成します。生成されたコードでは依存関係の注釈が省略されていることが多いため、必ず依存関係の注釈を確認してください。

AIツールはスコープ割り当てをキャプチャされたvm変数のプロパティとして書き換え、一致するすべてのビューバインディングにエイリアスをプレフィックスとして追加します。 Revスコープ オブジェクトが必要なため、$watch の呼び出しとイベント リスナーを手動で確認してください。