IT박스

dom 렌더링이 완료된 후 지시문을 실행하려면 어떻게해야합니까?

itboxs 2020. 7. 23. 19:42
반응형

dom 렌더링이 완료된 후 지시문을 실행하려면 어떻게해야합니까?


Angular JS 문서를 읽음으로써 명백한 해결책이없는 것처럼 보이는 간단한 문제가 있습니다.

DOM에서 컨테이너의 높이를 정의하기 위해 다른 DOM 요소의 높이를 기반으로 일부 계산을 수행하는 Angular JS 지시문이 있습니다.

이와 비슷한 것이 지시문 내에서 진행됩니다.

return function(scope, element, attrs) {
    $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
}

문제는 지시문이 실행될 때 $('site-header')찾을 수 없으며 jQuery 래핑 된 DOM 요소 대신 빈 배열을 반환한다는 것입니다.

DOM이로드 된 후에 만 ​​실행되는 지시문 내에서 사용할 수있는 콜백이 있습니까? 일반 jQuery 선택기 스타일 쿼리를 통해 다른 DOM 요소에 액세스 할 수 있습니까?


$ ( 'site-header') 구성 방법에 따라 다릅니다.

지연 시간 이 0 인 $ timeout사용해 볼 수 있습니다 . 다음과 같은 것 :

return function(scope, element, attrs) {
    $timeout(function(){
        $('.main').height( $('.site-header').height() -  $('.site-footer').height() );
    });        
}

작동 방식을 설명합니다 : one , two .

$timeout지시 에 주사하는 것을 잊지 마십시오 :

.directive('sticky', function($timeout)

내가하는 방법은 다음과 같습니다.

app.directive('example', function() {

    return function(scope, element, attrs) {
        angular.element(document).ready(function() {
                //MANIPULATE THE DOM
        });
    };

});

아마도 저자는 더 이상 내 대답이 필요하지 않을 것입니다. 여전히 완전성을 위해 다른 사용자가 유용하다고 생각합니다. 가장 좋고 가장 간단한 해결책은 $(window).load()반환 된 함수의 본문 내부에서 사용 하는 것입니다. (또는을 사용할 수 있습니다 document.ready. 모든 이미지가 필요한지 여부에 따라 다릅니다).

사용하여 $timeout내 소견에하는 것은 매우 약한 옵션이며 경우에 따라 실패 할 수 있습니다.

내가 사용할 완전한 코드는 다음과 같습니다.

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function($scope, $elem, attrs){

           $(window).load(function() {
               //...JS here...
           });
       }
   }
});

ngcontentloaded이벤트 있습니다. 사용할 수있을 것 같아요

.directive('directiveExample', function(){
   return {
       restrict: 'A',
       link: function(scope, elem, attrs){

                $$window = $ $window


                init = function(){
                    contentHeight = elem.outerHeight()
                    //do the things
                }

                $$window.on('ngcontentloaded',init)

       }
   }
});

If you can't use $timeout due to external resources and cant use a directive due to a specific issue with timing, use broadcast.

Add $scope.$broadcast("variable_name_here"); after the desired external resource or long running controller/directive has completed.

Then add the below after your external resource has loaded.

$scope.$on("variable_name_here", function(){ 
   // DOM manipulation here
   jQuery('selector').height(); 
}

For example in the promise of a deferred HTTP request.

MyHttpService.then(function(data){
   $scope.MyHttpReturnedImage = data.image;
   $scope.$broadcast("imageLoaded");
});

$scope.$on("imageLoaded", function(){ 
   jQuery('img').height(80).width(80); 
}

I had the a similar problem and want to share my solution here.

I have the following HTML:

<div data-my-directive>
  <div id='sub' ng-include='includedFile.htm'></div>
</div>

Problem: In the link-function of directive of the parent div I wanted to jquery'ing the child div#sub. But it just gave me an empty object because ng-include hadn't finished when link function of directive ran. So first I made a dirty workaround with $timeout, which worked but the delay-parameter depended on client speed (nobody likes that).

Works but dirty:

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        $timeout(function() {
            //very dirty cause of client-depending varying delay time 
            $('#sub').css(/*whatever*/);
        }, 350);
    };
    return directive;
}]);

Here's the clean solution:

app.directive('myDirective', [function () {
    var directive = {};
    directive.link = function (scope, element, attrs) {
        scope.$on('$includeContentLoaded', function() {
            //just happens in the moment when ng-included finished
            $('#sub').css(/*whatever*/);
        };
    };
    return directive;
}]);

Maybe it helps somebody.

참고URL : https://stackoverflow.com/questions/12240639/how-can-i-run-a-directive-after-the-dom-has-finished-rendering

반응형