Ich habe eine Funktion, die ich nach dem Laden von Seiteninhalten aufrufen möchte. Ich habe über $ viewContentLoaded gelesen und es funktioniert nicht für mich. Ich suche so etwas
document.addEventListener('DOMContentLoaded', function () {
//Content goes here
}, false);
Der oben genannte Anruf funktioniert bei AngularJs Controller nicht.
Laut Dokumentation von $ viewContentLoaded sollte es funktionieren
Wird jedes Mal gesendet, wenn der ngView-Inhalt neu geladen wird.
Es wird ein $viewContentLoaded
-Ereignis ausgegeben, das heißt, um dieses Ereignis zu erhalten, benötigen Sie einen übergeordneten Controller
<div ng-controller="MainCtrl">
<div ng-view></div>
</div>
Über MainCtrl
können Sie das Ereignis anhören
$scope.$on('$viewContentLoaded', function(){
//Here your view content is fully loaded !!
});
Überprüfen Sie die Demo
Angular <1.6.X
angular.element(document).ready(function () {
console.log('page loading completed');
});
Angular> = 1.6.X
angular.element(function () {
console.log('page loading completed');
});
Verwenden Sie eine Direktive und die Winkelelementmethode ready
wie folgt:
.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>
oder für diejenigen, die controller-as -Syntax verwenden ...
<div elem-ready="vm.someMethod()"></div>
Der Vorteil davon ist, dass Sie mit Ihrer Benutzeroberfläche so breit oder detailliert sein können, wie Sie möchten, und die DOM-Logik von Ihren Controllern entfernen. Ich würde argumentieren, dass dies der empfohlene Angular Weg ist.
Möglicherweise müssen Sie diese Direktive priorisieren, wenn andere Anweisungen auf demselben Knoten ausgeführt werden.
Sie können es direkt aufrufen, indem Sie nach dem HTML-Element {{YourFunction()}}
hinzufügen.
Hier ist ein Plunker Link
.
Diese Logik musste ich im Umgang mit Google-Diagrammen implementieren. Was ich getan habe, war, dass ich am Ende meiner HTML-Controller-Definition hinzugefügt habe.
<body>
-- some html here --
--and at the end or where ever you want --
<div ng-init="FunCall()"></div>
</body>
und in dieser Funktion rufen Sie einfach Ihre Logik auf.
$scope.FunCall = function () {
alert("Called");
}
sie können Javascript-Version des Onload-Ereignisses in eckigen js aufrufen. Dieses ng-load-Ereignis kann auf jedes dom-Element wie div, span, body, iframe, img usw. angewendet werden. Über den folgenden Link können Sie Ihrem vorhandenen Projekt ng-load hinzufügen.
download ng-load für eckige js
Das folgende Beispiel für iframe zeigt, dass nach dem Laden testCallbackFunction im Controller aufgerufen wird
BEISPIEL
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>
Wenn Sie bereits einen Fehler in $ Digest erhalten, kann dies helfen:
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
};
}] );
Obige Methode hat für mich funktioniert
Wenn Sie möchten, dass ein bestimmtes Element vollständig geladen wird, verwenden Sie ng-init für dieses Element.
z.B. <div class="modal fade" id="modalFacultyInfo" role="dialog" ng-init="initModalFacultyInfo()"> ..</div>
die Funktion initModalFacultyInfo () sollte im Controller vorhanden sein.
var myTestApp = angular.module("myTestApp", []);
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
alert("is called on page load.");
};
});
Ich habe {{myFunction()}}
in der Vorlage verwendet, aber dann einen anderen Weg gefunden here mit $timeout
im Controller. Ich dachte, ich würde es teilen, funktioniert für mich großartig.
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();
});
}]);
Ich habe festgestellt, dass bei verschachtelten Ansichten $ viewContentLoaded für jede der verschachtelten Ansichten ausgelöst wird. Ich habe diese Problemumgehung erstellt, um den endgültigen $ viewContentLoaded zu finden. Scheint in Ordnung zu funktionieren, wenn $ window.prerenderReady von Prerender festgelegt wird (geht in .run () in der Haupt-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 ++;
});
Das Ausführen nach dem Laden der Seite sollte teilweise erfüllt werden, indem ein Ereignislistener auf das Fensterladeereignis festgelegt wird
window.addEventListener("load",function()...)
Innerhalb der module.run(function()...)
von angle haben Sie Zugriff auf die Modulstruktur und Abhängigkeiten.
Sie können broadcast
- und emit
-Ereignisse für Kommunikationsbrücken verwenden.
Zum Beispiel:
Die Lösung, die für mich funktioniert, ist folgende
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);
}
});
}
}
}
}
}]);
Controller-Code lautet wie folgt
$scope.crearTooltip = function () {
$('[data-toggle="popover"]').popover();
}
HTML-Code lautet wie folgt
<tr ng-repeat="item in $data" on-finish-render="crearTooltip()">