スコープを変更してトラバースできるAngularアプリでモデルを内省/反映することは可能ですか? batarang のようなものがありますが、値を変更することができます。
そうでない場合、それを可能にするモンキー パッチ Angular コード (ページに別のスクリプトを含めることによって) は可能ですか?
スコープを変更してトラバースできるAngularアプリでモデルを内省/反映することは可能ですか? batarang のようなものがありますが、値を変更することができます。
そうでない場合、それを可能にするモンキー パッチ Angular コード (ページに別のスクリプトを含めることによって) は可能ですか?
1. スコープ プロパティへのアクセス/変更
Angular の$scope
オブジェクトは単純な古い JS オブジェクトであるため、標準的な方法で操作できます。
たとえばsomeScope.someProp
、プロパティの値を取得し、プロパティsomeScope.someProp = someValue
の値を設定します。
2. Angular に知らせる
オブジェクトのプロパティを変更することと、Angular に変更を認識させることは別のことです。
Angular は、$digest
サイクルを実行するまで、変更を認識しません。変更をすぐに適用したい場合は$digest
、 を使用してサイクルを明示的にトリガーできsomeScope.$apply()
ます。
3. スコープの入手
DOM 要素に関連付けられたスコープへの参照を取得するには、対応する DOM Node オブジェクトへの参照を取得し、それをラップしてそのメソッドangular.element
を実行する必要があります。
このようなもの:scope()
<body class="ng-scope">
var someScope = angular.element(document.body).scope();
$rootScope
さらに、 (すべてのスコープの親スコープ) にアクセスしたい場合は、インジェクターを使用して$rootScope
サービスを注入できます。
<html ng-app="myApp">
var injector = angular.element(document.documentElement).injector();
var rootScope = injector.get('$rootScope');
4. スコープ ツリーのトラバース
スコープ オブジェクトを取得したら、スコープ ツリーをトラバースすることをお勧めします。すべてのスコープには、(特に) 次のプロパティがあります。
$parent
: このスコープの親スコープ (存在する場合)。$$nextSibling
: このスコープの次の兄弟スコープ (存在する場合)。$parent
)$$childHead
: このスコープの最初の子スコープ (存在する場合)。someScope
ルートとしてスコープ ツリーのブランチをトラバースするには、次のようにします。
var scopes = [someScope];
while (scopes.length) {
var scope = scopes.shift();
console.log(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
たとえば、スコープ ツリー全体をトラバースするには、次のスニペットを使用できます。
var injector = angular.element(document.body).injector();
var rootScope = injector.get('$rootScope');
var scopes = [rootScope];
while (scopes.length) {
var scope = scopes.shift();
report(scope);
if (scope.$$nextSibling) { scopes.unshift(scope.$$nextSibling); }
if (scope.$$childHead) { scopes.unshift(scope.$$childHead); }
}
function report(scope) {
var str = '' + scope.$id;
while (scope.$parent) {
str = scope.$parent.$id + ' => ' + str;
scope = scope.$parent;
}
console.log(str);
}
scope()
によって返されたオブジェクトangular.element()
(または$()
、jQuery も使用している場合は ) でメソッドを呼び出すことにより、スコープを取得できますangular.element(".foo").scope()
。子スコープに直接アクセスする方法はありません。しかし、関連付けられた新しいスコープを持つすべての要素にはng-scope
クラスがあることがわかっているので、代わりに要素ツリーをたどることができます。
$(".foo").find(".ng-scope").each(function() {
var scope = $(this).scope();
});
ただし、深さに関係なく のfind()
下のすべてのノードが検出されるため、これは少し注意が必要です。代わりに.foo
使用できますが、 の直系の子孫が新しいスコープを作成しない可能性があるため、結果が得られない場合があります。children()
.foo