3

スコープを変更してトラバースできるAngularアプリでモデルを内省/反映することは可能ですか? batarang のようなものがありますが、値を変更することができます。

そうでない場合、それを可能にするモンキー パッチ Angular コード (ページに別のスクリプトを含めることによって) は可能ですか?

4

3 に答える 3

3

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);
}
于 2014-05-12T21:24:14.077 に答える
1

scope()によって返されたオブジェクトangular.element()(または$()、jQuery も使用している場合は ) でメソッドを呼び出すことにより、スコープを取得できますangular.element(".foo").scope()。子スコープに直接アクセスする方法はありません。しかし、関連付けられた新しいスコープを持つすべての要素にはng-scopeクラスがあることがわかっているので、代わりに要素ツリーをたどることができます。

$(".foo").find(".ng-scope").each(function() {
  var scope = $(this).scope();
});

ただし、深さに関係なく のfind()下のすべてのノードが検出されるため、これは少し注意が必要です。代わりに.foo使用できますが、 の直系の子孫が新しいスコープを作成しない可能性があるため、結果が得られない場合があります。children().foo

于 2014-05-12T17:53:24.183 に答える