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.
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
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');
});
Utilisez une directive et la méthode de l'élément angular ready
comme ceci:
.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);
})
})
}
}
})
<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.
Vous pouvez l'appeler directement en ajoutant {{YourFunction()}}
après l'élément HTML.
Voici un Plunker Link
.
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");
}
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>
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);
}
})
}
}
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
var myTestApp = angular.module("myTestApp", []);
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
alert("is called on page load.");
};
});
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();
});
}]);
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 ++;
});
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:
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()">