この記事の例では、AngularJS グローバル スコープと Isolate スコープの間の通信の使用法について説明します。参考のために皆さんと共有してください。詳細は次のとおりです。
プロジェクト開発中、グローバル スコープとディレクティブ ローカル スコープの使用範囲が十分に明確ではなく、グローバル スコープとディレクティブ ローカル スコープ間のコミュニケーションが十分に徹底されていません。ここで、グローバル スコープとディレクティブ ローカル スコープの使用について説明します。
1. スコープ
1. AngularJS では、子スコープは通常、JavaScript プロトタイプ継承メカニズムを通じて親スコープのプロパティとメソッドを継承します。ただし、例外があります。ディレクティブでscope: { ... }を使用する場合、この方法で作成されたスコープは独立した「分離」スコープになります。これには親スコープもありますが、親スコープはプロトタイプチェーン上にありません。親スコープからのプロトタイプの継承はありません。この方法でスコープを定義することは、通常、再利用可能なディレクティブ コンポーネントを構築するために使用されます。
2. 親スコープで定義されたプロパティに子スコープでアクセスすると、JavaScript はまず子スコープでプロパティを探します。プロトタイプ チェーンの親スコープから検索されます。まだ見つからない場合は、上位のプロトタイプ チェーンの親スコープで検索されます。 AngularJS では、スコープ プロトタイプ チェーンの最上位は $rootScope であり、JavaScript は $rootScope まで検索します。scope: { ... } - ディレクティブは、プロトタイプの継承なしで独立した「分離」スコープを作成します。これは、再利用可能なディレクティブ コンポーネントを作成する場合に最適なオプションです。親スコープのプロパティに直接アクセスしたり変更したりしないため、予期しない副作用は発生しません。
2. Isolate スコープの参照修飾子
1. = または =attr 「Isolate」スコープの属性は、どちらかの側の変更がもう一方の側に影響します。 ;
2. @ または @attr 「Isolate」スコープの属性は、親スコープの属性に一方向にバインドされます。つまり、「Isolate」スコープは、親スコープ。値は常に文字列型です。
3. & or &attr "Isolate" スコープは、親スコープの属性を関数にラップし、関数的な方法で親スコープの属性を読み書きします。パッケージ化メソッドは $parse です
3. ディレクティブとコントローラー データ転送と通信
1. 親コントローラーはグローバル スコープ (親スコープ) 変数をリッスンし、イベントを子スコープ (ディレクティブ スコープ、各ディレクティブ) にブロードキャストします。 scope)
2. ディレクティブはローカル スコープを定義します。=、@、& (メソッド) 文字を使用してグローバル スコープへの参照を表示します
3. ディレクティブ スコープ (サブスコープ) は、parent[$scope を介してグローバル スコープのプロパティを参照します。 .$parent.xxx]
4. ディレクティブはグローバル スコープ変数の変更を監視します。$scope.$parent.$watch メソッドを使用できます
IV. 例の説明
<div ng-controller="MyCtrl"> <button ng-click="show=true">show</button> <dialog title="Hello }" visible="}" on-cancel="show=false;" on-ok="show=false;parentScope();"> <!--上面的on-cancel、on-ok,是在directive的isoloate scope中通过&引用的。 如果表达式中包含函数,那么需要将函数绑定在parent scope(当前是MyCtrl的scope)中--> Body goes here: username:} , title:}. <ul> <!--这里还可以这么玩~names是parent scope的--> <li ng-repeat="name in names">}</li> </ul> <div> Email:<input type="text" ng-model="email" style="width: 200px;height:20px"/> </div> <div> Count:<input type="text" ng-model="person.Count" style="width: 120px;height:20px"/> <button ng-click="changeCount()">Count加1</button> </div> <p></p> </dialog> </div>
コントローラー テスト コード:
var app = angular.module("Dialog", []); app.controller("MyCtrl", function ($scope) { $scope.person = { Count: 0 }; $scope.email = 'carl@126.com'; $scope.names = ["name1", "name2", "name3"]; $scope.show = false; $scope.username = "carl"; $scope.title = "parent title"; $scope.parentScope = function () { alert("scope里面通过&定义的东东,是在父scope中定义"); }; $scope.changeCount = function () { $scope.person.Count = $scope.person.Count + 1; } // 监听controller count变更, 并发出事件广播,再directive 中 监听count CountStatusChange变更事件 $scope.$watch('person.Count', function (newVal, oldVal) { console.log('>>>parent Count change:' + $scope.person.Count); if (newVal != oldVal) { console.log('>>>parent $broadcast count change'); $scope.$broadcast('CountStatusChange', {"val": newVal}) } }); }); app.directive('dialog', function factory() { return { priority: 100, template: ['<div ng-show="visible">', ' <h3>}</h3>', ' <div class="body" ng-transclude></div>', ' <div class="footer">', ' <button ng-click="onOk()">OK</button>', ' <button ng-click="onCancel()">Close</button>', ' </div>', '</div>'].join(""), replace: false, transclude: true, restrict: 'E', scope: { title: "@",//引用dialog标签title属性的值 visible: "@",//引用dialog标签visible属性的值 onOk: "&",//以wrapper function形式引用dialog标签的on-ok属性的内容 onCancel: "&"//以wrapper function形式引用dialog标签的on-cancel属性的内容 }, controller: ['$scope', '$attrs', function ($scope, $attrs) { // directive scope title 通过@ 引用dialog标签title属性的值,所以这里能取到值 console.log('>>>title:' + $scope.title); >>>title:Hello carl scope.html:85 // 通过$parent直接获取父scope变量页可以 console.log('>>>parent username:' + $scope.$parent.username); >>>parent username:carl // directive scope 没有定义username 变量,并且没有引用父scope username变量, 所以这里是undefined console.log('>>>child username:' + $scope.username); >>>username:undefined // 接收由父controller广播count变更事件 $scope.$on('CountStatusChange', function (event, args) { console.log("child scope on(监听) recieve count Change event :" + args.val); }); // watch 父 controller scope对象 $scope.$parent.$watch('person.Count', function (newVal, oldVal) { console.log('>>>>>>>child watch parent scope[Count]:' + oldVal + ' newVal:' + newVal); }); }] }; });