컨텐츠가로드 된 후 호출 할 AngularJs 이벤트


163

페이지 내용이로드 된 후 호출하려는 기능이 있습니다. $ viewContentLoaded에 대해 읽었으며 작동하지 않습니다. 나는 무언가를 찾고있다.

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

AngularJs 컨트롤러에서는 위의 호출이 작동하지 않습니다.


1
이것은 잘 작동합니다 stackoverflow.com/q/14968690/6521116
Kris Roofe

답변:


163

$ viewContentLoaded의 문서에 따르면 작동해야합니다.

ngView 컨텐츠를 다시로드 할 때마다 발생합니다.

$viewContentLoaded 이 이벤트를 수신한다는 의미의 이벤트가 발생합니다.

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

에서 MainCtrl이 이벤트를들을 수 있습니다

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

데모 확인


59
이 방법의 문제점은이 시점에서 컨트롤러가 완전히 초기화되지 않았다는 것입니다.
Ash Blue

12
@Reza 그는 맞습니다.이 이벤트는 dom이 추가 될 때 앵귤러가 dom 처리를 완료하기 전에 시작됩니다. 각도 변수로 id 또는 클래스를 추가하여 이것을 테스트하고 jQuery를 사용하여 $ viewContentLoaded에서 찾아보십시오. 당신은 그것을 찾을 수 없습니다.
Thomas Kekeisen

1
@Reza yes, Thomas가 맞습니다. $ viewContentLoaded 내부에서 양식 요소에 액세스 할 수 없습니다 ($ scope.formName.elementName. $ setValidity ( "validateRule", false); "TypeError : 정의되지 않은 'elementName'속성을 읽을 수 없습니다"가 발생 함
Mussammil

2
$ rootScope 수준에서도 동일하게 호출 할 수 있습니다. $ scope. $ on 대신 $ rootScope. $ on 및 app.run () 블록 안에 있어야합니다.
Vil

4
이 옵션은 ng-repeat복잡한 루프 및 조건에 따라 HTML / 콘텐츠를 생성하는 여러 개의 중첩 된 지시문이 있는 경우에는 작동하지 않습니다 . $viewContentLoaded이벤트가 트리거 된 후에도 일정 시간 동안 렌더링이 계속됩니다 . 모든 요소가 완전히 렌더링되었는지 확인한 다음 특정 코드를 실행하는 방법은 무엇입니까? 아무 피드백?
tarekahf

104

각도 <1.6.X

angular.element(document).ready(function () {
    console.log('page loading completed');
});

각도> = 1.6.X

angular.element(function () {
    console.log('page loading completed');
});

이것은 app.js 내에 있습니까?
zcoon

3
당신은 당신의 controllers.js에서 그것을들을 수 있습니다
hariszaman

2
기본 app.js 파일에서도 정상적으로 작동합니다.
Loubot

그 대답은 저에게 효과적입니다! 문서 요소 페이지 'ready ()에서 더 이상 사용되지 않음 (더 이상 사용되지 않음, angular.element (document) .ready (callback)) 대신 angular.element (callback) 사용'
Lovera

이것은 나를 위해 일했습니다. 수락 된 답변 접근 방식이 컨트롤러 내부에서 작동하지 않습니다.
Fabiano

76

고정-2015.06.09

지시문과 각도 요소 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>

또는 컨트롤러로 구문을 사용 하는 사람들을 위해 ...

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

이것의 장점은 원하는만큼 UI를 넓게 또는 세분화 할 수 있고 컨트롤러에서 DOM 로직을 제거한다는 것입니다. 이것이 권장되는 Angular 방식 이라고 주장합니다 .

동일한 노드에서 다른 지시문이 작동하는 경우이 지시문의 우선 순위를 지정해야 할 수도 있습니다.


이것은 정말 좋은 해결책처럼 보이지만 작동시키지 못했습니다. elem.ready( $scope.$apply( readyFunc( $scope ))); 왜 그런지 아는 아이디어가 있습니까? 아마도 각도 업데이트가 일어 났습니까? 어쨌든-그것이 가능하다면 우아한 접근법입니다.
domoarigato 2016 년

1
nm, 문제가 무엇인지 알 수 있습니다. 에 오타가 있었으며 attrs.onReady현재 상태 여야합니다. 다른 문제는 내가 커피 스크립트를 메모리에서 JS로 변환 할 때 얻는 것을 펑키라고 부르는 것이었다.
jusopi

1
나는 어떤 경우에는 괜찮을 것이라고 생각하지만 그것에 대한 나의 주장은 다음과 같다. 나는 단지 글 렌싱 할 때 그의 코드에 대한 기대는 DOM에 표시하기 위해 텍스트 값을 반환하고, 조심스럽게 눈을 필요로한다고 생각한다. 지시어 우선 순위 측면에서 타이밍을 허용하지 않습니다. 사용하지 않으면 컨트롤러 수준에 머물러 있습니다 $timeout. 명시 적으로 addt을 작성 중입니다. DOM 노드는 단순히 비 DOM 논리를 실행합니다. 해당 메소드가 $ scope 계층 구조에서 멀리 떨어져 하위 범위가 상속하는 경우에만 재사용 할 수 있습니다. NG 관점에서는 좋지 않다고 생각합니다.
jusopi 2016 년

5
$timeout(function() {})주위를 추가 한 후 나를 위해 일했습니다 elem.ready(). 그렇지 않으면 $digest already in progress오류가 발생했습니다. 어쨌든, 고마워! 나는 지난 한 시간 동안 이것으로 어려움을 겪고있다.
rkrishnan

1
$ scope를 파는 것은 비어있는 것 같습니다. 어떤 아이디어?
MiloTheGreat

66

{{YourFunction()}}HTML 요소 다음 에 추가하여 직접 호출 할 수 있습니다 .

여기 Plunker Link있습니다.


6
제공하는 솔루션에 대한 설명을 조금 더 추가하여 답변을 더 자세히 설명해 주시겠습니까?
abarisone

해당 html 요소가로드 될 때 함수를 호출하고 싶다고 생각합니다. 따라서 위에서 언급 한대로 해당 함수를 호출하십시오. 내 추측이 당신의 의심에 대해 맞다면 이것이 효과가있을 것입니다. 그렇지 않으면 질문을 정교하게하십시오. :)
blue

14
이와 같은 함수를 호출 할 때. 한 번만 호출했는지 확인하십시오. 그렇지 않으면 다이제스트주기가 무한대로 실행되고 오류가 표시됩니다
Ashan

2
난이 용액 마찬가지로 정말 매우 단순
Kamuran Sönecek

1
이것은 환상적입니다-단 하나의 문제입니다. 이것을 사용할 때 내 기능이 5 번 실행되는 것 같습니다. 카운터가 추가되어 제대로 작동하지만 누군가 왜 그런 일이 일어날 지 알지 궁금합니다. 조금 이상하다고 생각하십니까?
itchyspacesuit

22

Google 차트를 처리하는 동안이 논리를 구현해야했습니다. 내가 한 것은 컨트롤러 정의 내부의 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");
}

나는 이것을 사용했지만 페이지 상단에 init에 ng-init를 페이지 하단으로 이동하여 일부 div를 이미로드해야했기 때문에 문제가 해결되었습니다.
Gurnard

내 문제에 도움이되는 답변 만 (jquery mobile empty selection)
kaiser

이것은 동적으로로드 된 컨트롤에 적응하고 구현하기가 쉽기 때문에 진정한 대답입니다.
Jason Sebring

이 답변을 통해 시간을 절약 할 수있었습니다. 사용 사례에 매우 우아하고 효과적이었습니다.
Sello

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

}] );

위의 방법은 나를 위해 일했습니다.


3

각도 js에서 onload 이벤트의 자바 스크립트 버전을 호출 할 수 있습니다. 이 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>

OP가 어떻게 문제를 해결할 수 있는지 보여주는 예제 코드를 추가하십시오
jro

@jro 내 ans를 업데이트했습니다. 도움이
되길

2

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

            })
        }
    }

0

이벤트 리스너를 창로드 이벤트로 설정하여 페이지로드 후 실행이 부분적으로 만족되어야합니다.

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

module.run(function()...)각도 안에는 모듈 구조와 종속성에 대한 모든 액세스 권한이 있습니다.

당신은 할 수 broadcastemit이벤트 통신 교량.

예를 들면 다음과 같습니다.

  • 모듈 세트 onload 이벤트 및 빌드 로직
  • 로직이 필요할 때 컨트롤러에 모듈 브로드 캐스트 이벤트
  • 컨트롤러는 모듈 onload 프로세스에 따라 자체 로직을 듣고 실행합니다.

0

나는 사용 된 {{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();
});

}]);

나는 모든 대답을 여기에서 시도했고 어떤 이유로 든 $ timeout이 나를 위해 일한 유일한 것입니다. 이유는 확실하지 않지만 ng-include 및 서비스 시작 타이밍과 관련이있을 수 있습니다.
Drellgor

{{myFunction ()}}에 대해 플러스 하나를 추가했습니다
commonpike

0

특정 요소를 완전히로드하려면 해당 요소에서 ng-init를 사용하십시오.

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

initModalFacultyInfo () 함수는 컨트롤러에 존재해야합니다.


0

중첩 된 뷰가있는 경우 $ 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
var myTestApp = angular.module("myTestApp", []); 
myTestApp.controller("myTestController", function($scope, $window) {
$window.onload = function() {
 alert("is called on page load.");
};
});

이 코드는 질문에 대답 할 수 있지만,이 코드가 질문에 응답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
rollstuhlfahrer

0

나를 위해 일하는 해결책은 다음과 같습니다.

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

-31

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

13
사람들이 여전히 추천합니까 setInterval 2016 년 솔루션으로 합니까?
Zachary Dahan 2016 년

그러나 agular에는 간단한 API가 없습니다 ... 어떻게 .. 어떻게해야합니까?
Piotr Kula
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.