ページのコンテンツが読み込まれた後に呼び出す関数があります。$ viewContentLoadedについて読みましたが、うまくいきません。私は何かを探しています
document.addEventListener('DOMContentLoaded', function () {
//Content goes here
}, false);
上記の呼び出しは、AngularJsコントローラーでは機能しません。
ページのコンテンツが読み込まれた後に呼び出す関数があります。$ 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 !!
});
デモを確認する
ng-repeat
複雑なループと条件に基づいてHTML /コンテンツを生成するいくつかのネストされたディレクティブがある場合、このオプションは機能しません。$viewContentLoaded
イベントがトリガーされた後でも、レンダリングはしばらく続きます。すべての要素が完全にレンダリングされていることを確認してから、特定のコードを実行するにはどうすればよいですか?フィードバックはありますか?
角度<1.6.X
angular.element(document).ready(function () {
console.log('page loading completed');
});
角度> = 1.6.X
angular.element(function () {
console.log('page loading completed');
});
ディレクティブと次の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構文を使用している人のために...
<div elem-ready="vm.someMethod()"></div>
これの利点は、UIを好きなだけ広くまたはきめ細かくすることができ、コントローラーからDOMロジックを削除することです。これが推奨されるAngularの方法であると私は主張します。
同じノードで他のディレクティブが動作している場合は、このディレクティブに優先順位を付ける必要がある場合があります。
elem.ready( $scope.$apply( readyFunc( $scope )));
なぜそれがそうであるかもしれない考えで窒息しました おそらく角度の更新が起こったのでしょうか?とにかく-それがうまくいけば、それはエレガントなアプローチです。
attrs.onReady
はずです。もう1つの問題は、私がそれをファンキーと呼んでいることでした... ...コーヒースクリプトをメモリからJSに変換することで得られるもの。
$timeout
。使用しない限り、コントローラーレベルでスタックします。あなたは明示的にaddtを作成しています。非DOMロジックを実行するためのDOMノード。そのメソッドが$ scope階層のはるか上位にあり、子スコープが継承する場合にのみ再利用できます。NGの観点では見た目が悪いと思います。
$timeout(function() {})
たelem.ready()
。それ以外の場合は、$digest already in progress
エラーをスローしていました。とにかく、トンに感謝!私は過去1時間、これに苦労しています。
{{YourFunction()}}
HTML要素の後に追加することで、直接呼び出すことができます。
こちらが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");
}
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
};
}] );
上記の方法は私のために働きました
Angular jsでJavaScriptバージョンのonloadイベントを呼び出すことができます。この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);
}
})
}
}
ページ読み込み後に実行するには、イベントリスナーをウィンドウ読み込みイベントに設定することで部分的に満たす必要があります
window.addEventListener("load",function()...)
内部 module.run(function()...)
angularの、モジュールの構造と依存関係にすべてアクセスできます。
次のことが可能broadcast
とemit
コミュニケーションブリッジのためのイベント。
例えば:
私は{{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();
});
}]);
特定の要素を完全にロードする場合は、その要素でng-initを使用します。
例えば <div class="modal fade" id="modalFacultyInfo" role="dialog" ng-init="initModalFacultyInfo()"> ..</div>
initModalFacultyInfo()関数がコントローラーに存在する必要があります。
ネストされたビューがある場合、ネストされたすべてのビューに対して$ 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 ++;
});
var myTestApp = angular.module("myTestApp", []);
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
alert("is called on page load.");
};
});
私のために働く解決策は次のとおりです
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()">
setInterval
コンテンツが読み込まれるのを待つために使用します。これが問題の解決に役立つことを願っています。
var $audio = $('#audio');
var src = $audio.attr('src');
var a;
a = window.setInterval(function(){
src = $audio.attr('src');
if(src != undefined){
window.clearInterval(a);
$('audio').mediaelementplayer({
audioWidth: '100%'
});
}
}, 0);
setInterval
解決策として推奨していますか?