Angular.js: angular.element.scope () devuelve indefinido

Creado en 9 oct. 2014  ·  29Comentarios  ·  Fuente: angular/angular.js

angular.element.scope () no está definido cuando la aplicación se carga en iframe cambiando el atributo iframe src.

El siguiente código debería devolver una referencia al alcance pero devuelve undefined:

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

El código anterior se ejecuta en el controlador onclick después de que se carga el documento y angular ha terminado de arrancar:

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

El problema se manifiesta solo cuando el documento se carga en el iframe modificando su atributo src.
Probado con 1.3.0-rc.5, sin jquery.

jqLite more info

Comentario más útil

Si desea habilitar la información de depuración temporalmente (por ejemplo, para depurar un problema en una aplicación de producción en vivo) puede usar angular.reloadWithDebugInfo() como se describe aquí .

Todos 29 comentarios

¿Puede proporcionar una reproducción plnkr del problema, por favor?

Tengo el mismo problema en mi propio proyecto, pero no puedo reproducirlo usando plnkr.

scope () devuelve undefined en cualquier elemento.

El uso de JQLite o JQuery 2.1.1 hace lo mismo.

AngularJS 1.3.1.

Prueba esto:

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

¿Está deshabilitando la información de depuración en su proyecto @VictorQueiroz?

@caitp Lo has encontrado.

Habilitar la información de depuración de nuevo es una buena solución para este problema.

una buena solución

:sonríe sonríe Sonríe:

Lo siento chicos por no reaccionar por un tiempo. El problema está relacionado de alguna manera con jqCache, o más específicamente con la forma en que se crea expandoId. En RC más antiguos, la identificación se creó así:
var expandoId = element[JQLite.expando];
En los más nuevos, la identificación se obtiene usando la propiedad codificada:
var expandoId = element.ng339;
Revertir el cambio resolvió el problema.
Desafortunadamente, no sé mucho sobre el material, por lo que si alguien pudiera arrojar luz sobre la funcionalidad, entonces tal vez podría describir el problema con más detalle.

¡Oh, wow, gracias @caitp que me estaba volviendo loco!
Debería haber una nota en el documento sobre $ compileProvider que explique que $compileProvider.debugInfoEnabled(false) hará que la función scope() regrese indefinida, si ese es el comportamiento esperado.

Editar: mi mal, ya está en el documento.

Llame a este método para habilitar / deshabilitar diversa información de tiempo de ejecución de depuración en el compilador, como agregar información de enlace y una referencia al alcance actual en los elementos DOM.

Hay alguna forma de evitar esto; habiendo debugInfoEnabled (false), pero aún siendo capaz de acceder al alcance de un elemento?

Si desea habilitar la información de depuración temporalmente (por ejemplo, para depurar un problema en una aplicación de producción en vivo) puede usar angular.reloadWithDebugInfo() como se describe aquí .

¡Creo que @gkalpak aclaró las cosas aquí!

¿Por qué cerrar? Encontrar una solución alternativa no significa que el problema esté solucionado, el alcance () debería devolver el alcance adjunto independientemente del modo de depuración.

Si no es posible, debe estar claramente documentado en angular.element #scope () doc.

@Toilal Lo he cerrado porque ya está documentado como se mencionó en los comentarios anteriores de este hilo. ¡Pero si cree que debería documentarse en otros lugares también, agradeceríamos mucho a un PR!

No puedo porque no estoy seguro de que los métodos brujos de angular.element no funcionen al deshabilitar la depuración. scope () seguro porque lo he probado, pero ¿qué hay de los demás, como controller (), injector () ...

Después de la prueba, solo afecta a scope () y isolateScope (). Los documentaré y haré un PR.

Pero, ¿hay alguna forma de recuperar el alcance de un elemento DOM mientras se tiene deshabilitada la información de depuración?

@Toilal - no realmente - la información del alcance se eliminó ya que exponer que tiene un impacto en el rendimiento, es por eso que está oculta detrás de una bandera de depuración.

Pero no sería tan difícil escribir una directiva que pudiera hacer eso y ponerla en los elementos que necesita verificar.

Gracias @ pkozlowski-opensource. Agregué una pequeña oración sobre scope () y isolateScope () en documentos, porque me lleva algunas veces averiguar por qué esos métodos no funcionaron en mi aplicación.

@ocombe Eso es lo que haré, porque estoy escribiendo un componente de interfaz de usuario y no puedo confiar en scope / isolateScope ya que el desarrollador final podría deshabilitar la información de depuración (como se recomienda).

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

qq 20160115164505

@ronnievdv

Hay alguna forma de evitar esto; habiendo debugInfoEnabled (false), pero aún siendo capaz de acceder al alcance de un elemento?

He usado el siguiente método snipet _ (no recomendado) _ en la función link de la definición de la directiva.

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

¿Hay alguna forma de verificar si debugInfo se ha deshabilitado o alguna marca para ello?

Desde dentro de la aplicación, puede usar $compileProvider.debugInfoEnabled() .
Si desea depurar una instancia en vivo que tiene la información de depuración deshabilitada (por ejemplo, una implementación de producción), puede llamar a angular.reloadWithDebugInfo() desde la consola y volverá a cargar la aplicación con la información de depuración habilitada.

@gkalpak Solo quiero verificar si la información de depuración está habilitada o no. Algo así.

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

@hemkaran , todavía no es obvio desde dónde quiere verificarlo. Supongo desde dentro de su aplicación.
Si ese es el caso, puede usar $compileProvider.debugInfoEnabled() .

@Toilal ¿
cc @ocombe

Lo siento, ya no uso Angular 1, y nunca tuve que escribir una directiva de este tipo (porque solo necesitaba esta información en el modo de desarrollo)

Hice lo siguiente. Veremos si mis compañeros de equipo lo dejarán pasar la revisión :)

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

También puede establecer $ isolateScope en el mismo valor si lo necesita.

¿Fue útil esta página
0 / 5 - 0 calificaciones