Angular.js: angle.element.scope() gibt undefined zurück

Erstellt am 9. Okt. 2014  ·  29Kommentare  ·  Quelle: angular/angular.js

angle.element.scope() ist undefiniert, wenn die Anwendung in iframe geladen wird, indem das iframe-src-Attribut geändert wird.

Der folgende Code sollte einen Verweis auf den Bereich zurückgeben, gibt jedoch undefiniert zurück:

angular.element(document.body).scope()

Der obige Code wird im onclick-Handler ausgeführt, nachdem das Dokument geladen wurde und angle das Bootstrap beendet hat:

<script>
    document.addEventListener("click", function(){
        console.log(angular.element(document.body).scope());
    });
</script>

Das Problem tritt nur auf, wenn das Dokument in den iframe geladen wird, indem sein src-Attribut geändert wird.
Getestet mit 1.3.0-rc.5, ohne jquery.

jqLite more info

Hilfreichster Kommentar

Wenn Sie Debug-Informationen vorübergehend aktivieren möchten (z. B. zum Debuggen eines Problems in einer Live-Produktions-App), können Sie wie hier beschrieben angular.reloadWithDebugInfo() .

Alle 29 Kommentare

Können Sie bitte eine plnkr-Reproduktion des Problems bereitstellen?

Ich habe das gleiche Problem in meinem eigenen Projekt, kann es aber nicht mit plnkr reproduzieren.

scope() gibt undefined für jedes Element zurück.

Die Verwendung von JQLite oder JQuery 2.1.1 bewirkt dasselbe.

AngularJS 1.3.1.

Versuche dies:

document.addEventListener('DOMContentLoaded', function () {
  angular.element(document.body).scope();
});

deaktivieren Sie Debug-Informationen in Ihrem Projekt @VictorQueiroz?

@caitp Du hast es gefunden.

Das Aktivieren der Debug-Informationen ist eine gute Problemumgehung für dieses Problem.

ein guter workaround

:Lächeln lächeln lächeln:

Sorry Leute, dass ich eine Weile nicht reagiert habe. Das Problem hängt irgendwie mit jqCache zusammen, oder genauer gesagt mit der Art und Weise, wie expandoId erstellt wird. In älteren RCs wurde die ID wie folgt erstellt:
var expandoId = element[JQLite.expando];
In neueren Versionen wird die ID mit der hartcodierten Eigenschaft abgerufen:
var expandoId = element.ng339;
Das Zurücksetzen der Änderung hat das Problem behoben.
Leider kenne ich mich mit dem Zeug nicht so gut aus, wenn also jemand etwas über die Funktionalität sagen könnte, könnte ich das Problem vielleicht genauer beschreiben.

Oh wow danke @caitp das hat mich wahnsinnig gemacht!
Es sollte einen Hinweis im Dokument zum $compileProvider geben, der erklärt, dass $compileProvider.debugInfoEnabled(false) die scope() Funktion undefiniert zurückgeben lässt, wenn dies das erwartete Verhalten ist.

Edit: mein Fehler, es ist schon im doc

Rufen Sie diese Methode auf, um verschiedene Debug-Laufzeitinformationen im Compiler zu aktivieren/deaktivieren, z. B. das Hinzufügen von Bindungsinformationen und einem Verweis auf den aktuellen Bereich zu DOM-Elementen.

Gibt es einen Weg, dies zu umgehen; debugInfoEnabled(false) haben, aber trotzdem auf den Bereich eines Elements zugreifen können?

Wenn Sie Debug-Informationen vorübergehend aktivieren möchten (z. B. zum Debuggen eines Problems in einer Live-Produktions-App), können Sie wie hier beschrieben angular.reloadWithDebugInfo() .

Ich denke, dass @gkalpak hier die

Warum schließen? Das Finden einer Problemumgehung bedeutet nicht, dass das Problem behoben ist, scope() sollte den angehängten Bereich unabhängig vom Debug-Modus zurückgeben.

Wenn dies nicht möglich ist, sollte dies in angle.element #scope() doc klar dokumentiert werden.

@Toilal Ich habe es geschlossen, da es bereits dokumentiert ist, wie in den vorherigen Kommentaren dieses Threads erwähnt. Aber wenn Sie der Meinung sind, dass es auch an anderen Stellen dokumentiert werden sollte, wäre eine PR sehr dankbar!

Ich kann nicht, weil ich nicht sicher bin, ob Hexenmethoden von angle.element beim Deaktivieren des Debug nicht funktionieren. scope () auf jeden Fall, weil ich es ausprobiert habe, aber wie sieht es mit den anderen aus, wie Controller (), Injektor () ...

Nach dem Testen wirkt es sich nur auf scope() und isolateScope() aus. Ich werde diese dokumentieren und eine PR machen.

Aber gibt es eine Möglichkeit, den Bereich von einem DOM-Element abzurufen, während die Debug-Informationen deaktiviert sind?

@Toilal - nicht wirklich - Scope-Informationen wurden entfernt, da sie sich auf die Perf auswirken - deshalb sind sie hinter einem Debug-Flag versteckt.

Aber es wäre nicht so schwer, eine Direktive zu schreiben, die das tun könnte, und sie auf die Elemente zu setzen, die Sie überprüfen müssen

Danke @pkozlowski-opensource. Ich habe in den Dokumenten einen kleinen Satz zu scope() und isolateScope() hinzugefügt, da ich einige Zeit brauche, um herauszufinden, warum diese Methoden in meiner Anwendung nicht funktioniert haben.

@ocombe Das werde ich tun, weil ich eine UI-Komponente schreibe und mich nicht auf Scope/IsolateScope verlassen kann, da der Endentwickler Debug-Informationen deaktivieren könnte (wie empfohlen).

setTimeout(Funktion() {
console.log(angular.element(document.body).scope());
}, 100);

qq 20160115164505

@ronnievdv

Gibt es einen Weg, dies zu umgehen; debugInfoEnabled(false) haben, aber trotzdem auf den Bereich eines Elements zugreifen können?

Ich habe die folgende Snipet-Methode _(nicht empfohlen)_ in der link Funktion der Direktivendefinition verwendet.

link: function(scope, element, attrs) {
  var isolatedScope = scope.$$childTail;
}

Gibt es eine Möglichkeit zu überprüfen, ob debugInfo deaktiviert wurde oder ein Flag dafür?

In der App können Sie $compileProvider.debugInfoEnabled() .
Wenn Sie eine Live-Instanz mit deaktivierten Debug-Informationen debuggen möchten (z. B. eine Produktionsbereitstellung), können Sie angular.reloadWithDebugInfo() von der Konsole aus aufrufen und die App wird mit aktivierten Debug-Informationen neu geladen.

@gkalpak Ich möchte nur überprüfen, ob Debug-Informationen aktiviert sind oder nicht. Irgendwie so.

if(angular.isDebugInfoEnabled()) {
  // Do something
}

@hemkaran , es ist immer noch nicht offensichtlich, _wo_ Sie es überprüfen möchten. Ich nehme an, von innerhalb Ihrer App.
Wenn dies tatsächlich der Fall ist, können Sie $compileProvider.debugInfoEnabled() .

@Toilal Hast du so eine Anweisung geschrieben? Wenn ja, würde es Ihnen etwas ausmachen zu teilen? Ich habe dieses Problem gerade. Ich gehe davon aus, dass ich eine Lösung finden werde, aber eine zweite Meinung zu haben, wie man es löst, würde wirklich nicht schaden.
cc @ocombe

Entschuldigung, ich benutze Angular 1 nicht mehr und musste nie eine solche Direktive schreiben (weil ich diese Informationen nur im Entwicklungsmodus benötigte)

Ich habe folgendes gemacht. Wir werden sehen, ob meine Teamkollegen es durch die Überprüfung durchlassen :)

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);
        }
    };

Sie können bei Bedarf auch $isolateScope auf denselben Wert setzen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen