アプリケーションがiframesrc属性を変更してiframeに読み込まれると、angular.element.scope()は未定義になります。
次のコードはスコープへの参照を返す必要がありますが、未定義を返します。
angular.element(document.body).scope()
上記のコードは、ドキュメントが読み込まれ、angularがブートストラップを終了した後、onclickハンドラーで実行されます。
<script>
document.addEventListener("click", function(){
console.log(angular.element(document.body).scope());
});
</script>
この問題は、ドキュメントがsrc属性を変更してiframeに読み込まれた場合にのみ発生します。
jqueryなしで1.3.0-rc.5でテストされました。
問題のplnkr複製を提供できますか?
私自身のプロジェクトでも同じ問題がありますが、plnkrを使用して再現することはできません。
scope()は、どの要素でも未定義を返します。
JQLiteまたはJQuery2.1.1を使用しても同じことができます。
AngularJS1.3.1。
これを試して:
document.addEventListener('DOMContentLoaded', function () {
angular.element(document.body).scope();
});
プロジェクト@VictorQueirozのデバッグ情報を無効にしていますか?
@caitpあなたはそれを見つけました。
デバッグ情報を有効に戻すことは、この問題の適切な回避策です。
良い回避策
:smile :: smile :: smile:
しばらく反応しなかったのでごめんなさい。 この問題は、どういうわけかjqCacheに関連しており、より具体的には、expandoIdの作成方法に関連しています。 古いRCでは、IDは次のように作成されていました。
var expandoId = element[JQLite.expando];
新しいものでは、IDはハードコードされたプロパティを使用して取得されます。
var expandoId = element.ng339;
変更を元に戻すと、問題が解決しました。
残念ながら、私はその内容についてあまり知らないので、誰かが機能に光を当てることができれば、おそらく私は問題をより詳細に説明することができるでしょう。
私を怒らせていた@caitpに感謝します!
$ compileProviderのドキュメントに、予想される動作である場合、 $compileProvider.debugInfoEnabled(false)
によってscope()
関数が未定義で返されることを説明するメモがあります。
編集:私の悪い、それはすでにドキュメントにあります
このメソッドを呼び出して、バインディング情報や現在のスコープへの参照をDOM要素に追加するなど、コンパイラでさまざまなデバッグランタイム情報を有効/無効にします。
これを回避する方法はありますか。 debugInfoEnabled(false)がありますが、それでも要素のスコープにアクセスできますか?
@gkalpakはここで
なぜ閉じるのですか? 回避策を見つけても問題が修正されるわけではありません。scope()は、デバッグモードに関係なく、アタッチされたスコープを返す必要があります。
不可能な場合は、 angular.element #scope()ドキュメントに明確に文書化する必要があります。
@Toilalこのスレッドの以前のコメントで述べたように、すでに文書化されているので、閉じました。 しかし、他の場所でも文書化する必要があると思われる場合は、PRをいただければ幸いです。
デバッグを無効にすると、angular.elementのwitchメソッドが機能しないかどうかわからないため、できません。 scope()は試したので確かですが、controller()、injector()などの他のものはどうですか...
テスト後、scope()とisolateScope()にのみ影響します。 それらを文書化してPRします。
しかし、デバッグ情報を無効にした状態でDOM要素からスコープを取得する方法はありますか?
@ Toilal-実際にはそうではありません-スコープ情報は、パフォーマンスに影響を与えるため、削除されました-これが、デバッグフラグの背後に隠されている理由です。
しかし、それを実行できるディレクティブを作成して、チェックする必要のある要素に配置することはそれほど難しくありません。
@ pkozlowski-オープンソースに感謝します。 docsのscope()とisolateScope()に小さな文を追加しました。これは、これらのメソッドがアプリケーションで機能しなかった理由を理解するのに時間がかかるためです。
@ocombeこれを実行します
setTimeout(function(){
console.log(angular.element(document.body).scope());
}、100);
@ronnievdv
これを回避する方法はありますか。 debugInfoEnabled(false)がありますが、それでも要素のスコープにアクセスできますか?
ディレクティブ定義のlink
関数で次のsnipet _(非推奨)_メソッドを使用しました。
link: function(scope, element, attrs) {
var isolatedScope = scope.$$childTail;
}
debugInfoが無効になっているかどうか、またはそのフラグを確認する方法はありますか?
アプリ内から、 $compileProvider.debugInfoEnabled()
使用できます。
デバッグ情報が無効になっているライブインスタンスをデバッグする場合(本番環境のデプロイなど)、コンソールからangular.reloadWithDebugInfo()
を呼び出すと、デバッグ情報が有効になっているアプリが再読み込みされます。
@gkalpakデバッグ情報が有効になっているかどうかを確認したいだけです。 ややこのように。
if(angular.isDebugInfoEnabled()) {
// Do something
}
@hemkaran 、それをどこからチェックしたいかはまだ明らかではありません。 私はあなたのアプリの中から推測します。
それが実際に当てはまる場合は、 $compileProvider.debugInfoEnabled()
使用できます。
@Toilalそのようなディレクティブを書きましたか? もしそうなら、共有していただけませんか? 私は今この問題を抱えています。 私は解決策を見つけると思いますが、それを解決する方法についてセカンドオピニオンを持っていても実際には害はありません。
cc @ocombe
申し訳ありませんが、Angular 1はもう使用していません。また、そのようなディレクティブを作成する必要はありませんでした(開発モードでこの情報が必要なだけだったため)
私は次のことをしました。 チームメイトがレビューを通過できるかどうかを確認します:)
function exposeScope() {
return {
restrict: 'A',
link: function(scope, element) {
element[0].APPNAME = {
getScope: function() {
return scope;
}
};
}
};
}
return {
restrict: 'A',
scope: false,
link: function(scope, elem) {
elem.data('$scope', scope);
}
};
必要に応じて、$ isolateScopeを同じに設定することもできます。
最も参考になるコメント
デバッグ情報を一時的に有効にする場合(たとえば、ライブの本番アプリで問題をデバッグする場合)、ここで説明するように
angular.reloadWithDebugInfo()
を使用できます。