web-dev-qa-db-ja.com

コンテンツがロードされた後に呼び出すAngularJsイベント

ページコンテンツが読み込まれた後に呼び出したい関数があります。 $ viewContentLoadedについて読みましたが、うまくいきません。探している

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

上記の呼び出しはAngularJsコントローラでは動作しません。

149
user3233772

$ viewContentLoaded のドキュメントによると、それは動作するはずです

NgViewコンテンツがリロードされるたびに発行されます。

$viewContentLoadedイベントが発行されます。つまり、このイベントを受け取るには、親コントローラが必要です。

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

MainCtrlからあなたはイベントを聞くことができます

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

デモ を確認してください

155
Reza

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');
});
92
hariszaman

修正済み - 2015.06.09

次のようにディレクティブとangle要素のreadyメソッドを使います。

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>

または controller-as / syntax ...を使っている人のために.

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

これの利点はあなたが好きなようにあなたのUIと同じくらい広いか細かいことができ、あなたがあなたのコントローラからDOMロジックを削除していることです。これがお勧めです Angular 方法です。

同じノードで他のディレクティブが動作している場合は、このディレクティブを優先させる必要があります。

73
jusopi

HTML要素の後に{{YourFunction()}}を追加することで直接呼び出すことができます。

これは Plunker Link です。

56
blue

私はグーグルチャートで処理しながらこのロジックを実装しなければなりませんでした。私がやったのは、私が追加したコントローラ定義内の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");
}
18
Saad Zulfiqar

あなたは角度jsでonloadイベントのJavaScript版を呼び出すことができます。このng-loadイベントは、div、span、body、iframe、imgなどのDOM要素に適用できます。以下は、既存のプロジェクトにng-loadを追加するためのリンクです。

角度jsの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>
3
Darshan Jain

$ 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);
                }

            })
        }
    }
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
    };

}] );

上記の方法は私のために働いた

2
Alok D

特定の要素を完全にロードしたい場合は、その要素に対してng-initを使用してください。

例えば<div class="modal fade" id="modalFacultyInfo" role="dialog" ng-init="initModalFacultyInfo()"> ..</div>

initModalFacultyInfo()関数はコントローラに存在するはずです。

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

私はテンプレートで{{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();
});

}]);
0
Nhan

入れ子になったビューがある場合、$ 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 ++;
});
0
Maksym

ウィンドウロードイベントにイベントリスナを設定することで、ページロード後に実行を部分的に満たす必要があります。

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

module.run(function()...)の中であなたはモジュール構造と依存関係へのすべてのアクセスを持つでしょう。

通信ブリッジ用にbroadcastおよびemitイベントがあります。

例えば:

  • モジュールがonloadイベントを設定し、ロジックを構築
  • ロジックが要求したときにコントローラにモジュールブロードキャストイベント
  • コントローラはモジュールのonloadプロセスに基づいて独自のロジックをリッスンして実行します。

私のために働く解決策は以下の通りです

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()">
0