「どのようにthis
して$scope
AngularJSコントローラで動作しますか?」
短い答え:
this
- コントローラーコンストラクター関数が呼び出される
this
と、コントローラーになります。
$scope
オブジェクトで定義されたthis
関数が呼び出されると、「関数が呼び出されたときに有効なスコープ」になります。これは$scope
、関数が定義されている場合とそうでない場合があります。だから、関数の内部、this
および$scope
かもしれないと同じこと。
$scope
- すべてのコントローラには、関連付けられた
$scope
オブジェクトがあります。
- コントローラー(コンストラクター)関数は、それに関連付けられたのモデルプロパティと関数/動作を設定します
$scope
。
$scope
HTML /ビューからアクセスできるのは、このオブジェクト(およびプロトタイプ継承が機能している場合は親スコープオブジェクト)で定義されているメソッドだけです。たとえば、ng-click
フィルタ、などから
長い答え:
コントローラ関数はJavaScriptコンストラクタ関数です。コンストラクター関数が実行されるとき(たとえば、ビューが読み込まれるとき)、this
(つまり、「関数コンテキスト」)がコントローラーオブジェクトに設定されます。したがって、「タブ」コントローラーコンストラクター関数では、addPane関数が作成されます。
this.addPane = function(pane) { ... }
$ scopeではなく、コントローラーオブジェクト上に作成されます。ビューはaddPane関数を見ることができません-ビューは$ scopeで定義された関数にのみアクセスできます。つまり、HTMLでは、これは機能しません。
<a ng-click="addPane(newPane)">won't work</a>
「タブ」コントローラーコンストラクター関数が実行されると、次のようになります。
黒い破線は、プロトタイプの継承を示しています。分離スコープは、プロトタイプとしてスコープから継承します。(HTMLでディレクティブが検出された有効なスコープからプロトタイプを継承しません。)
現在、ペインディレクティブのリンク関数は、タブディレクティブと通信する必要があります(これは、タブに影響を与える必要があるため、$ scopeを何らかの方法で分離する必要があります)。イベントを使用することもできますが、別のメカニズムは、ペインディレクティブをrequire
タブコントローラーにすることです。(require
タブ$ scope へのペインディレクティブにはメカニズムがないようです。)
したがって、これは問題を引き起こします:タブコントローラーへのアクセスしか持っていない場合、どのようにしてタブへのアクセスを取得して$ scopeを分離しますか(これは本当に必要なものです)?
さて、赤い点線が答えです。addPane()関数の「スコープ」(ここではJavaScriptの関数スコープ/クロージャーを指します)は、関数にタブ分離$ scopeへのアクセスを提供します。つまり、addPane()が定義されたときに作成されたクロージャが原因で、addPane()は上の図の「タブIsolateScope」にアクセスできます。(代わりに、タブ$ scopeオブジェクトにaddPane()を定義した場合、ペインディレクティブはこの関数にアクセスできないため、タブ$ 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
の$scope
。メソッドの内部には、$scope
まだParentCtrl
の$ scopeがあります。
フィドル
this
特にng-repeat、ng-include、ng-switch、およびディレクティブがすべて独自の子スコープを作成できることを考えると、影響を受ける$ scopeが混乱するため、$ scopeで定義された関数内では使用しないようにします。