web-dev-qa-db-fra.com

Evénement AngularJs à appeler après le chargement du contenu

J'ai une fonction que je veux appeler une fois le contenu de la page chargé. J'ai lu sur $ viewContentLoaded et cela ne fonctionne pas pour moi. Je cherche quelque chose comme 

document.addEventListener('DOMContentLoaded', function () { 
     //Content goes here 
}, false);

L’appel ci-dessus ne fonctionne pas pour moi dans le contrôleur AngularJs.

145
user3233772

Selon la documentation de $ viewContentLoaded , cela est supposé fonctionner

Émis chaque fois que le contenu ngView est rechargé.

L'événement $viewContentLoaded est émis, ce qui signifie que pour recevoir cet événement, vous avez besoin d'un contrôleur parent tel que

<div ng-controller="MainCtrl">
  <div ng-view></div>
</div>

De MainCtrl vous pouvez écouter l'événement

  $scope.$on('$viewContentLoaded', function(){
    //Here your view content is fully loaded !!
  });

Vérifiez la Démo

155
Reza

Angulaire <1.6.X

angular.element(document).ready(function () {
    console.log('page loading completed');
});

Angulaire> = 1.6.X

angular.element(function () {
    console.log('page loading completed');
});
91
hariszaman

fixe - 2015.06.09

Utilisez une directive et la méthode de l'élément angular ready comme ceci:

js

.directive( 'elemReady', function( $parse ) {
   return {
       restrict: 'A',
       link: function( $scope, elem, attrs ) {    
          elem.ready(function(){
            $scope.$apply(function(){
                var func = $parse(attrs.elemReady);
                func($scope);
            })
          })
       }
    }
})

html

<div elem-ready="someMethod()"></div>

ou pour ceux qui utilisent la syntaxe controller-as ...

<div elem-ready="vm.someMethod()"></div>

L'avantage de ceci est que vous pouvez être aussi large ou granulaire que votre interface utilisateur et que vous supprimez la logique DOM de vos contrôleurs. Je dirais que c'est la méthode recommandée angulaire.

Vous devrez peut-être donner la priorité à cette directive si d'autres directives fonctionnent sur le même nœud.

71
jusopi

Vous pouvez l'appeler directement en ajoutant {{YourFunction()}} après l'élément HTML.

Voici un Plunker Link .

55
blue

Je devais mettre en œuvre cette logique lors de la manipulation avec Google Maps. ce que j'ai fait, c'est qu'à la fin de mon code html, à l'intérieur de la définition du contrôleur, j'ai ajouté.

  <body>
         -- some html here -- 
--and at the end or where ever you want --
          <div ng-init="FunCall()"></div>
    </body>

et dans cette fonction, appelez simplement votre logique.

$scope.FunCall = function () {
        alert("Called");
}
18
Saad Zulfiqar

vous pouvez appeler la version javascript de l'événement onload en js angulaire. Cet événement ng-load peut être appliqué à tout élément dom tel que div, span, body, iframe, img, etc. Ce lien vous permet d'ajouter ng-load à votre projet existant.

télécharger ng-load pour js angulaire

Voici un exemple pour l'iframe, une fois qu'il est chargé testCallbackFunction sera appelé dans le contrôleur

EXEMPLE

JS

    // include the `ngLoad` module
    var app = angular.module('myApp', ['ngLoad']);
    app.controller('myCtrl', function($scope) {
        $scope.testCallbackFunction = function() {
          //TODO : Things to do once Element is loaded
        };

    });  

HTML

  <div ng-app='myApp' ng-controller='myCtrl'> 
      <iframe src="test.html" ng-load callback="testCallbackFunction()">  
  </div>
3
Darshan Jain

Si vous obtenez une erreur $ digest déjà en cours, cela pourrait aider:

return {
        restrict: 'A',
        link: function( $scope, elem, attrs ) {
            elem.ready(function(){

                if(!$scope.$$phase) {
                    $scope.$apply(function(){
                        var func = $parse(attrs.elemReady);
                        func($scope);
                    })
                }
                else {

                    var func = $parse(attrs.elemReady);
                    func($scope);
                }

            })
        }
    }
2
John Smith
var myM = angular.module('data-module');

myM.directive('myDirect',['$document', function( $document ){

    function link( scope , element , attrs ){

        element.ready( function(){

        } );

        scope.$on( '$viewContentLoaded' , function(){

            console.log(" ===> Called on View Load ") ;

        } );

    }

    return {
        link: link
    };

}] );

La méthode ci-dessus a fonctionné pour moi

2
Alok D
var myTestApp = angular.module("myTestApp", []); 
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
 alert("is called on page load.");
};
});
0
Shreyansh Kumar

J'utilisais {{myFunction()}} dans le modèle mais j'ai ensuite trouvé un autre moyen ici en utilisant $timeout dans le contrôleur. Je pensais que je le partagerais, ça fonctionnait très bien pour moi.

angular.module('myApp').controller('myCtrl', ['$timeout',
function($timeout) {
var self = this;

self.controllerFunction = function () { alert('controller function');}

$timeout(function () {
    var vanillaFunction = function () { alert('Vanilla function'); }();
    self.controllerFunction();
});

}]);
0
Nhan

J'ai constaté que si vous avez des vues imbriquées, $ viewContentLoaded est déclenché pour chacune des vues imbriquées. J'ai créé cette solution de contournement pour trouver la dernière $ viewContentLoaded. Semble fonctionner correctement pour définir $ window.prerenderReady comme requis par Prerender (entre dans .run () dans le fichier principal app.js):

// Trigger $window.prerenderReady once page is stable
// Note that since we have nested views - $viewContentLoaded is fired multiple
// times and we need to go around this problem
var viewContentLoads = 0;
var checkReady = function(previousContentLoads) {
  var currentContentLoads = Number(viewContentLoads) + 0; // Create a local copy of the number of loads
  if (previousContentLoads === currentContentLoads) { // Check if we are in a steady state
    $window.prerenderReady = true; // Raise the flag saying we are ready
  } else {
    if ($window.prerenderReady || currentContentLoads > 20) return; // Runaway check
    $timeout(function() {checkReady(currentContentLoads);}, 100); // Wait 100ms and recheck
  }
};
$rootScope.$on('$stateChangeSuccess', function() {
  checkReady(-1); // Changed the state - ready to listen for end of render
});
$rootScope.$on('$viewContentLoaded', function() {
  viewContentLoads ++;
});
0
Maksym

L'exécution après le chargement de la page devrait être partiellement satisfaite en définissant un écouteur d'événement sur l'événement de chargement de fenêtre

window.addEventListener("load",function()...)

Dans la module.run(function()...) de angular, vous aurez tous les accès à la structure du module et à ses dépendances.

Vous pouvez broadcast et emit événements pour les ponts de communication. 

Par exemple:

  • module set onload event et logique de construction
  • module de diffusion d'événement aux contrôleurs lorsque la logique l'exige
  • les contrôleurs écoutent et exécutent leur propre logique en fonction des processus de module onload.
0

La solution qui fonctionne pour moi est la suivante

app.directive('onFinishRender', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                    if (!!attr.onFinishRender) {
                        $parse(attr.onFinishRender)(scope);
                    }
                });
            }

            if (!!attr.onStartRender) {
                if (scope.$first === true) {
                    $timeout(function () {
                        scope.$emit('ngRepeatStarted');
                        if (!!attr.onStartRender) {
                            $parse(attr.onStartRender)(scope);
                        }
                    });
                }
            }
        }
    }
}]);

Le code du contrôleur est le suivant

$scope.crearTooltip = function () {
     $('[data-toggle="popover"]').popover();
}

Le code HTML est le suivant

<tr ng-repeat="item in $data" on-finish-render="crearTooltip()">
0
Jorge Santos Neill