ページコンテンツが読み込まれた後に呼び出したい関数があります。 $ viewContentLoadedについて読みましたが、うまくいきません。探している
document.addEventListener('DOMContentLoaded', function () {
//Content goes here
}, false);
上記の呼び出しはAngularJsコントローラでは動作しません。
$ viewContentLoaded のドキュメントによると、それは動作するはずです
NgViewコンテンツがリロードされるたびに発行されます。
$viewContentLoaded
イベントが発行されます。つまり、このイベントを受け取るには、親コントローラが必要です。
<div ng-controller="MainCtrl">
<div ng-view></div>
</div>
MainCtrl
からあなたはイベントを聞くことができます
$scope.$on('$viewContentLoaded', function(){
//Here your view content is fully loaded !!
});
デモ を確認してください
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');
});
次のようにディレクティブとangle要素のready
メソッドを使います。
.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>
または controller-as / syntax ...を使っている人のために.
<div elem-ready="vm.someMethod()"></div>
これの利点はあなたが好きなようにあなたのUIと同じくらい広いか細かいことができ、あなたがあなたのコントローラからDOMロジックを削除していることです。これがお勧めです Angular 方法です。
同じノードで他のディレクティブが動作している場合は、このディレクティブを優先させる必要があります。
HTML要素の後に{{YourFunction()}}
を追加することで直接呼び出すことができます。
これは Plunker Link
です。
私はグーグルチャートで処理しながらこのロジックを実装しなければなりませんでした。私がやったのは、私が追加したコントローラ定義内のHTMLの最後にあるということでした。
<body>
-- some html here --
--and at the end or where ever you want --
<div ng-init="FunCall()"></div>
</body>
その関数では、単にあなたのロジックを呼び出します。
$scope.FunCall = function () {
alert("Called");
}
あなたは角度jsでonloadイベントのJavaScript版を呼び出すことができます。このng-loadイベントは、div、span、body、iframe、imgなどのDOM要素に適用できます。以下は、既存のプロジェクトにng-loadを追加するためのリンクです。
以下はiframeの例です。ロードされると testCallbackFunction がコントローラで呼び出されます
_例_
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>
$ digestがすでに進行中のエラーになっている場合は、これが役立ちます。
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
};
}] );
上記の方法は私のために働いた
特定の要素を完全にロードしたい場合は、その要素に対してng-initを使用してください。
例えば<div class="modal fade" id="modalFacultyInfo" role="dialog" ng-init="initModalFacultyInfo()"> ..</div>
initModalFacultyInfo()関数はコントローラに存在するはずです。
var myTestApp = angular.module("myTestApp", []);
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
alert("is called on page load.");
};
});
私はテンプレートで{{myFunction()}}
を使っていましたが、それから別の方法を見つけました ここ コントローラの中で$timeout
を使うこと。私はそれを共有したいと思った、私にとっては素晴らしい作品。
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();
});
}]);
入れ子になったビューがある場合、$ viewContentLoadedが入れ子になったすべてのビューに対してトリガーされることがわかりました。この回避策を作成して、最後の$ viewContentLoadedを見つけました。 Prerenderで要求されているように$ window.prerenderReadyを設定しても問題ないようです(メインのapp.jsの.run()に入ります)。
// 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 ++;
});
ウィンドウロードイベントにイベントリスナを設定することで、ページロード後に実行を部分的に満たす必要があります。
window.addEventListener("load",function()...)
module.run(function()...)
の中であなたはモジュール構造と依存関係へのすべてのアクセスを持つでしょう。
通信ブリッジ用にbroadcast
およびemit
イベントがあります。
例えば:
私のために働く解決策は以下の通りです
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);
}
});
}
}
}
}
}]);
コントローラコードは以下の通りです
$scope.crearTooltip = function () {
$('[data-toggle="popover"]').popover();
}
HTMLコードは以下の通りです
<tr ng-repeat="item in $data" on-finish-render="crearTooltip()">