[解決済み] AngularJS コントローラにおける 'this' と $scope の比較
質問
で AngularJSのホームページの"Create Components"セクションにある には、このような例があります。
controller: function($scope, $element) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
}
this.addPane = function(pane) {
if (panes.length == 0) $scope.select(pane);
panes.push(pane);
}
}
がどのように
select
メソッドが追加され
$scope
を指定する必要がありますが
addPane
メソッドが追加されます。
this
. もし、これを
$scope.addPane
で、コードが壊れる。
ドキュメントには、実際に違いがあることは書かれていますが、その違いが何であるかについては触れられていません。
以前のバージョン(1.0 RC以前)のAngularでは
this
と互換性があります。$scope
メソッドがありますが、これはもはや事実ではありません。スコープ上で定義されたメソッドの内部でthis
と$scope
は交換可能です(角度セットthis
を$scope
) を使用しますが、それ以外のコントローラコンストラクタ内では使用しません。
どのように
this
と
$scope
は、AngularJSのコントローラで動作しますか?
どのように解決するのですか?
<ブロッククオート
どのように
this
と
$scope
は、AngularJSのコントローラで動作するのですか?
短い回答 :
-
this
-
コントローラコンストラクタ関数が呼び出されたとき。
this
がコントローラです。 -
に定義された関数が
$scope
オブジェクトが呼び出される。this
は、関数が呼び出されたときに有効だったスコープです" 。 このスコープが$scope
で定義された関数です。 つまり、関数の内部でthis
と$scope
よろしい ない は同じです。
-
コントローラコンストラクタ関数が呼び出されたとき。
-
$scope
-
すべてのコントローラには、関連する
$scope
オブジェクトを作成します。 -
コントローラ (コンストラクタ) 関数は、モデルのプロパティを設定し、関連する
$scope
. -
このメソッドで定義されたメソッドのみ
$scope
オブジェクト (およびプロトタイプ継承が行われている場合はその親スコープオブジェクト) に HTML/view からアクセスすることができます。 例えばng-click
, フィルタなど。
-
すべてのコントローラには、関連する
長い回答 :
コントローラ関数は、JavaScriptのコンストラクタ関数です。 コンストラクタ関数が実行されるとき(例えば、ビューがロードされるとき)。
this
(すなわち、"function context") にコントローラオブジェクトが設定されます。つまり、コントローラのコンストラクタ関数において、addPane関数が生成される際に
this.addPane = function(pane) { ... }
は、コントローラオブジェクトで作成され、 $scope ではありません。 ビューは addPane 関数を見ることができません -- ビューは $scope で定義された関数にしかアクセスできません。 言い換えると、HTML上では、これは動作しません。
<a ng-click="addPane(newPane)">won't work</a>
コントローラコンストラクタ関数が実行された後、以下のようになります。
黒の破線はプロトタイプの継承を示し、アイソレートのスコープはプロトタイプの継承で スコープ . (HTMLの中でそのディレクティブに出会ったときのスコープからは、プロトタイプ的に継承されません)。
さて、pane ディレクティブの link 関数は、tabs ディレクティブと通信したいと考えています (つまり、tabs isolate $scope に何らかの形で影響を与える必要があるということです)。 イベントを使用することもできますが、他の方法として、ペインディレクティブが
require
をタブコントローラーに設定します。 (ペインディレクティブがタブコントローラになる仕組みはないようです。
require
を指定します)。
もし、tabs コントローラにしかアクセスできないのなら、 (本当に必要な)tabs isolate $scope にはどのようにアクセスするのでしょうか?
さて、赤い点線がその答えです。 addPane() 関数の "scope" (ここでは JavaScript の関数スコープ/クロージャを参照しています) は、タブ孤立 $scope へのアクセスを関数に与えています。 つまり、addPane() が上の図の "tabs IsolateScope" にアクセスできるのは、addPane() を定義したときに作成されたクロージャのためです。 (代わりに tabs $scope オブジェクトに addPane() を定義した場合、pane ディレクティブはこの関数にアクセスできず、したがって tabs $scope と通信する方法がありません)。
質問のもう一つの部分にお答えします。
how does $scope work in controllers?
:
scopeで定義された関数内。
this
には、その関数が呼び出された場所/時に有効な$scopeが設定されます"。 例えば、以下のようなHTMLがあったとします。
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
そして
ParentCtrl
(ソール)には
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
最初のリンクをクリックすると、次のように表示されます。
this
と
$scope
は同じなので、"
この関数が呼び出されたときに有効だったスコープ
に関連付けられたスコープです。
ParentCtrl
.
2つ目のリンクをクリックすると
this
と
$scope
は
ではない
は同じなので、"。
この関数が呼び出されたときに有効だったスコープ
に関連付けられているスコープです。
ChildCtrl
. そこで、ここでは
this
が設定されています。
ChildCtrl
's
$scope
. メソッドの内部で
$scope
は、やはり
ParentCtrl
の$scopeを使用します。
を使用しないようにしています。
this
ng-repeat、ng-include、ng-switch、およびディレクティブがすべて独自の子スコープを作成できることを特に考慮して、どの$scopeが影響を受けるのかがわからなくなるためです。
関連
-
[解決済み] オブジェクトと選択機能を備えたAngularJS BootstrapUI Typeahead
-
[解決済み] AngularJs ReferenceError: $http is not defined
-
[解決済み] AngularJS の ng-disabled ディレクティブに式を指定しても動作しない
-
[解決済み] AngularJS 。scope.apply()呼び出し時の$digest already in progressエラーを防ぐ。
-
[解決済み] AngularJSの.$on()とは?
-
[解決済み] AngularJSでデータバインディングはどのように機能するのですか?
-
[解決済み] コールバック内で正しい `this` にアクセスする方法
-
[解決済み] AngularJSを使用して、ブラウザのコンソールで$scope変数にアクセスするにはどうすればよいですか?
-
[解決済み] AngularJSで$scope.$watchと$scope.$applyを使用するにはどうすればよいですか?
-
[解決済み】AngularJSのディレクティブスコープにおける「@」と「=」の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] オブジェクトと選択機能を備えたAngularJS BootstrapUI Typeahead
-
[解決済み] AngularJs ReferenceError: $http is not defined
-
[解決済み] Angular JS $locationChangeStart 次の url ルートオブジェクトを取得する
-
[解決済み] AngularJsでng-Cloakディレクティブを実際に使用する方法とは?
-
[解決済み] エラーです。[$injector:unpr] 不明なプロバイダです。ルートプロバイダ
-
AngularJS がエラー $digest already in progress を報告する
-
[解決済み] どのように$state.goにパラメータを追加しますか?
-
[解決済み] angular.serviceとangular.factoryの比較
-
[解決済み] コントローラでフィルタを使用するには?
-
[解決済み] AngularJSでコントローラを2回実行する場合の対処法