Cómo ejecutar la función en el controlador angular en el documento listo?


Tengo una función dentro de mi controlador angular, me gustaría que esta función se ejecute en document ready, pero me di cuenta de que angular la ejecuta a medida que se crea el dom.

 function myController($scope)
 {
     $scope.init = function()
     {
        // I'd like to run this on document ready
     }

     $scope.init(); // doesn't work, loads my init before the page has completely loaded
 }

¿Alguien sabe cómo puedo hacer esto?

Author: Damjan Pavlica, 2013-09-06

9 answers

Podemos usar el método angular.element(document).ready() para adjuntar callbacks para cuando el documento esté listo. Simplemente podemos adjuntar la devolución de llamada en el controlador de la siguiente manera:

angular.module('MyApp', [])

.controller('MyCtrl', [function() {
    angular.element(document).ready(function () {
        document.getElementById('msg').innerHTML = 'Hello';
    });
}]);

Http://jsfiddle.net/jgentes/stwyvq38/1 /

 424
Author: Will,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-30 11:33:18

Ver este post Cómo ejecutar la función de controlador angular en la carga de la página?
Para búsqueda rápida:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

De esta manera, no tiene que esperar hasta que el documento esté listo.

 27
Author: vinesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32

Angular se inicializa automáticamente en el evento DOMContentLoaded o cuando el angular.el script js se evalúa si en ese momento el documento.readyState se establece en 'completar'. En este punto Angular busca la ng-app directiva que designa la raíz de la aplicación.

Https://docs.angularjs.org/guide/bootstrap

Esto significa que el código del controlador se ejecutará después de que el DOM esté listo.

Por lo tanto es solo $scope.init().

 21
Author: Will M,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-10 15:03:09

Angular tiene varios puntos de tiempo para comenzar a ejecutar funciones. Si buscas algo como jQuery

$(document).ready();

Puede encontrar este análogo en angular para ser muy útil:

$scope.$watch('$viewContentLoaded', function(){
    //do something
});

Este es útil cuando desea manipular los elementos DOM. Comenzará a ejecutarse solo después de que se carguen todos los elementos te.

UPD: Lo que se ha dicho anteriormente funciona cuando se desea cambiar las propiedades css. Sin embargo, a veces no funciona cuando se desea medir las propiedades del elemento, tales como anchura, altura, etc. En este caso, es posible que desee probar esto:

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});
 12
Author: Alex Link,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-15 15:03:04

Tuve una situación similar en la que necesitaba ejecutar una función de controlador después de que se cargara la vista y también después de que se cargara, inicializara y colocara una referencia a sí mismo en $scope. Lo que terminó funcionando para mí fue configurar un reloj en esta propiedad scope y disparar mi función solo después de que se inicializara.

// $scope.myGrid property will be created by the grid itself
// The grid will have a loadedRows property once initialized

$scope.$watch('myGrid', function(newValue, oldValue) {
    if (newValue && newValue.loadedRows && !oldValue) {
        initializeAllTheGridThings();
    }
});

El vigilante es llamado un par de veces con valores indefinidos. Luego, cuando se crea la cuadrícula y tiene la propiedad esperada, la función de inicialización puede ser llamada de forma segura. La primera vez que el observador es llamado con un newValue no indefinido, oldValue seguirá siendo indefinido.

 2
Author: MikeyM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-27 15:30:12

Aquí está mi intento dentro de un controlador externo usando coffeescript. Funciona bastante bien. Tenga en cuenta que la configuración.pantalla.xs / sm|md / lg son valores estáticos definidos en un archivo no uglificado que incluyo con la aplicación. Los valores son por los puntos de interrupción oficiales de Bootstrap 3 para los tamaños de consulta de medios del mismo nombre:

xs = settings.screen.xs // 480
sm = settings.screen.sm // 768
md = settings.screen.md // 992
lg = settings.screen.lg // 1200

doMediaQuery = () ->

    w = angular.element($window).width()

    $scope.xs = w < sm
    $scope.sm = w >= sm and w < md
    $scope.md = w >= md and w < lg
    $scope.lg = w >= lg
    $scope.media =  if $scope.xs 
                        "xs" 
                    else if $scope.sm
                        "sm"
                    else if $scope.md 
                        "md"
                    else 
                        "lg"

$document.ready () -> doMediaQuery()
angular.element($window).bind 'resize', () -> doMediaQuery()
 1
Author: akutz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-06 19:52:10

La respuesta

$scope.$watch('$viewContentLoaded', 
    function() { 
        $timeout(function() {
            //do something
        },0);    
});

Es el único que funciona en la mayoría de los escenarios que probé. En una página de ejemplo con 4 componentes que construyen HTML a partir de una plantilla, el orden de los eventos era

$document ready
$onInit
$postLink
(and these 3 were repeated 3 more times in the same order for the other 3 components)
$viewContentLoaded (repeated 3 more times)
$timeout execution (repeated 3 more times)

Así que un document documento.ready() es inútil en la mayoría de los casos, ya que el DOM que se está construyendo en angular puede estar lejos de estar listo.

Pero más interesante, incluso después de fired viewContentLoaded disparado, el elemento de interés todavía no se pudo encontrar.

Solo después de que se ejecute tim timeout fue encontrado. Tenga en cuenta que a pesar de que el tim timeout era un valor de 0, pasaron casi 200 milisegundos antes de que se ejecutara, lo que indica que este subproceso se mantuvo apagado durante bastante tiempo, presumiblemente mientras que el DOM tenía plantillas angulares agregadas en un subproceso principal. El tiempo total desde el primer document documento.ready () hasta la última ejecución tim timeout fue de casi 500 milisegundos.

En un caso extraordinario donde se estableció el valor de un componente y luego se cambió el valor de text() más tarde en el tim timeout, el el valor de tim timeout tuvo que ser aumentado hasta que funcionó (aunque el elemento pudo ser encontrado durante el tim timeout). Algo asincrónico dentro del componente de tercera parte hizo que un valor tuviera prioridad sobre el texto hasta que pasara el tiempo suficiente. Otra posibilidad es $scope.$evalAsync, pero no fue probado.

Todavía estoy buscando ese evento que me dice que el DOM se ha establecido completamente y puede ser manipulado para que todos los casos funcionen. Hasta ahora es necesario un valor de tiempo de espera arbitrario, lo que significa que, en el mejor de los casos, este es un kludge que puede no funcionar en un navegador lento. No he probado las opciones de jQuery como liveQuery y publish / subscribe que pueden funcionar, pero ciertamente no son angulares puros.

 1
Author: Wray Smallwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-21 17:49:46

¿Por qué no probar con qué documentos de angular mencionan https://docs.angularjs.org/api/ng/function/angular.element .

Angular.element (callback)

He usado esto dentro de mi on OnInit () {...} función.

 var self = this;

 angular.element(function () {
        var target = document.getElementsByClassName('unitSortingModule');
        target[0].addEventListener("touchstart", self.touchHandler, false);
        ...
    });

Esto funcionó para mí.

 0
Author: Mahib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-04 22:22:27
$scope.$on('$ViewData', function(event) {
//Your code.
});
 0
Author: Shreyansh Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-23 06:56:11