AngularJSにおける$scopeとは何ですか?例を用いたチュートリアル
⚡ スマートサマリー
AngularJS の $Scope は、コントローラとビューをバインドする組み込みオブジェクトです。このページでは、スコープの作成、動作関数、親と子の階層構造、$rootScope との違い、およびダイジェストサイクルによるバインディングの更新方法について説明します。
AngularJS の $scope とは何ですか?
AngularJS の $scope 基本的に「コントローラー」と「ビュー」をバインドする組み込みオブジェクトです。 コントローラー内のスコープでメンバー変数を定義すると、ビューからアクセスできます。
すべてのコントローラー AngularJS アプリケーションは依存性注入によって独自の $scope インスタンスを受け取ります。そのオブジェクトにアタッチしたものはすべて、コントローラが管理するテンプレートから見えるようになります。そのため、$scope は、アプリケーションとコントローラの間にある共有データ モデルとして機能します。 JavaスクリプトのロジックとHTMLマークアップ。
以下の例を考えてみましょう。
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code 説明:
- モジュールの名前は「アプリ」です
- コントローラーの名前は「HelloWorldCtrl」です。
- Scope オブジェクトは、コントローラーからビューに情報を渡すために使用される主要なオブジェクトです。
- メンバー変数がスコープオブジェクトに追加されました
⚠️ 構文警告: その .controller() メソッドはコントローラ名とファクトリ関数の 2 つの引数を取るので、間にカンマが必要です 'HelloWorldCtrl' (NAIST) と function($scope). コンマを省略すると、 Uncaught SyntaxError AngularJSが起動する前。
単一のコントローラーと単一のビューだけでは、全体像の半分しか捉えられません。実際のアプリケーションでは、コントローラーがネストされ、リストが繰り返し使用され、ウィジェットが再利用されるため、複数のスコープが同時に存在します。
AngularJSにおけるスコープ階層と継承の仕組み
AngularJSアプリケーションには必ず1つのルートスコープがあり、子スコープはいくつでも持つことができます。ディレクティブはこれらの子スコープを作成し、装飾するDOM要素にアタッチするため、スコープツリーはレンダリングされたページの構造を反映します。
AngularJS が次のような式を評価するとき {{siteName}}まず、要素にアタッチされたスコープでそのプロパティを探します。プロパティが存在しない場合は、親スコープに検索範囲が移り、ルートスコープに到達するまで検索を続けます。 Javaスクリプト開発者はこの動作をプロトタイプ継承と呼び、子スコープはまさにそのようにして親スコープから継承します。
以下の例では、コントローラーを別のコントローラーの中にネストすることで、継承がどのように行われるかを確認できます。
<div ng-app="scopeDemo"> <div ng-controller="ParentCtrl"> Parent scope value: {{siteName}} <div ng-controller="ChildCtrl"> Child reads parent value: {{siteName}} Child own value: {{lesson}} </div> </div> </div> <script type="text/javascript"> var app = angular.module("scopeDemo", []); app.controller("ParentCtrl", function($scope) { $scope.siteName = "Guru99"; }); app.controller("ChildCtrl", function($scope) { $scope.lesson = "AngularJS Scope"; }); </script>
Code 説明:
ParentCtrl定義siteNameそれ自身の範囲内で。ChildCtrl定義しないsiteNameしかし、内部のdivは依然として Guru99 なぜなら、ルックアップは親スコープまで遡るからです。lesson子要素のスコープ内でのみ存在するため、親要素のdivからは読み取ることができません。
どの指示によって新しいスコープが作成されますか?
- ng-controller: 配置先の要素に対して子スコープを作成します。
- ng-repeat: 反復処理ごとに1つの子スコープが作成されるため、各行は同じ式に対して異なる値を保持できます。
- カスタム指示: 子どものスコープを要求するか、 隔離する 意図的に親クラスから継承しないスコープ。
- コンポーネント指示: 登録されているもの
.component()ヘルパーは常に分離スコープを受け取ります。
子スコープは上位レベルまで読み込まれるため、開発者はしばしばそのチェーンの最上位がどこにあるのか疑問に思うことがあります。その最上位オブジェクトは$rootScopeと呼ばれます。
$scopeと$rootScopeの違いは何ですか?
AngularJS $rootScope はアプリケーション全体のスコープです。アプリケーションには $rootScope が 1 つしか存在できず、グローバル変数のように使用されます。すべての $scope は子スコープであり、$rootScope はツリーの最上位にある親スコープです。以下の表は、これら 2 つのオブジェクトを比較したものです。
| 側面 | $スコープ | $rootScope |
|---|---|---|
| アプリケーションごとのインスタンス数 | コントローラーまたはスコープ作成ディレクティブごとに1つずつ、多数存在する。 | ちょうど1つ |
| によって作成された | ng-controller や ng-repeat などのディレクティブ | アプリケーション起動時のインジェクター |
| 透明性 | その元素とそのすべての子孫 | アプリケーション内のすべてのスコープ |
| 典型的な使用 | 1つのビューまたは1つのリスト行のデータと動作 | アプリケーション全体の値(ログインユーザーなど) |
| 主なリスク | ブランチ外では値にアクセスできなくなります | 名前衝突や隠れた結合(グローバル変数など) |
$rootScope は控えめに使用してください。そこに配置したものはアプリケーション全体で存在し、どこからでも読み取り可能になるため、通常は共有サービスの方がグローバルステートの安全な場所となります。 $rootScope 参照 完全なAPI一覧が表示されます。
データの保存場所を把握することは、仕事の半分に過ぎません。残りの半分は、ユーザーが何らかの操作を行った際に、スコープがどのように反応するかを教えることです。
AngularJSで動作を設定または追加する
イベントに反応したり、ビュー内で何らかの計算/処理を実行したりするには、スコープに動作を提供する必要があります。
ビヘイビアーは、ビューによってトリガーされる可能性のある特定のイベントに応答するためにスコープ オブジェクトに追加されます。 コントローラーで動作を定義すると、ビューからアクセスできるようになります。
これを実現する方法の例を見てみましょう。
<!DOCTYPE html> <html lang="en"> <head> <meta chrset="UTF 8"> <title>Guru99</title> </head> <body ng-app="DemoApp"> <h1> Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <div ng-controller="DemoController"> {{fullName("Guru","99")}} </div> <script type="text/javascript"> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { $scope.fullName=function(firstName,lastname){ return firstName + lastname; } } ); </script> </body> </html>
Code 説明:
- 「fullName」という動作を作成しています。 この動作は、2 つのパラメーター (firstName、lastname) を受け入れる関数です。
- その後、動作はこれら 2 つのパラメーターを連結したものを返します。
- ビューでは、動作を呼び出し、2 つの値を渡しています。Guru」と「99」は、動作のパラメータとして渡されます。
コマンドが正常に実行された場合、ブラウザでコードを実行すると次の出力が表示されます。
出力:
ブラウザには、両方の値の連結が表示されます。 Guru 99 は、 コントローラ.
上記のようなバインディングは自動的に更新されるため、アプリケーションが大規模になる前に、その仕組みを理解しておくことは重要です。
スコープウォッチャーとダイジェストサイクルが重要な理由
AngularJSは、変更イベントではなくダーティチェックによってビューをスコープと同期させます。このプロセスは、以下の3つのスコープAPIによって実現されます。
- $watch: 式のリスナーを登録します。補間式は、
{{fullName}}テンプレートのリンク時に、監視者を自動的に登録します。 - $適用: AngularJSの実行コンテキストに入り、コードを評価してからダイジェストをトリガーします。組み込みのディレクティブは既にこの関数を呼び出すため、カスタムイベントコールバックまたはサードパーティライブラリのコールバック内でのみ必要です。
- $digest: $rootScopeとその子要素上のすべてのウォッチャーを走査し、現在の値を前の値と比較し、モデルが変更されなくなるまで繰り返します。
ダイジェストは複数回実行される可能性があるため、ウォッチ式は低コストに保つ必要があります。DOM の読み取りは、データの読み取りよりも桁違いに遅いため、ウォッチ式内で DOM アクセスは避けてください。 Javaスクリプトプロパティ。
監視の深さもコストに影響します。参照による監視は最も速く、価値全体が交換されたときにのみ検知します。 $watchCollection 配列またはオブジェクト内で追加、削除、または並べ替えられた項目を通知します。値による監視は、ダイジェストごとにネストされた構造を走査するため、最もコストのかかるオプションです。したがって、最後に使用するようにしてください。




