programing

각도 뒤에 jQuery 코드 실행JS가 HTML 렌더링을 완료합니다.

linuxpc 2023. 3. 17. 19:39
반응형

각도 뒤에 jQuery 코드 실행JS가 HTML 렌더링을 완료합니다.

$http $resource JSON의 $http $resource입니다. 이 를 $.JS의 HTML을 사용합니다.는 Angular로 채워진 목록의 요소입니다.ng-repeat시시 구조 갱신을 한 후 .【Angular】DOM 【javascript】 【javascript】떻게게 하면 ?? ???지난 4시간 동안 인터넷을 검색해 봤지만 아무런 해결책을 찾지 못했어요.

JSON 데이터를 수신하는 방법은 다음과 같습니다.

var tradesInfo = TradesInfo.get({}, function(data){
    console.log(data);
    $scope.source.profile = data.profile;
            $scope.trades = $scope.source.profile.trades;
        $scope.activetrade = $scope.trades[0];
        $scope.ready = true;

           
    init();  //I need to call this function after update is complete
    
});

이런 이 일어나죠.init()★★★★

function init(){
    alert($('#wrapper').width());
    alert($('#wrapper').height());
}

이 문제를 해결할 수 있는 쉬운 방법이 있을 거라는 건 알지만 지금 당장 찾을 수는 없어요.

사실 이 경우 각도 방식이 쉬운 방법이 아니라 올바른 방법입니다.

지시문을 작성하고 높이를 알고 싶은 요소에 부착해야 합니다.컨트롤러에서 이벤트를 $broadcast하면 디렉티브가 이벤트를 포착하고 거기서 DOM 조작을 실행할 수 있습니다.컨트롤러에는 없습니다.

var tradesInfo = TradesInfo.get({}, function(data){
    console.log(data);
    $scope.source.profile = data.profile;
    ...

    $scope.$broadcast('dataloaded');
});


directive('heightStuff', ['$timeout', function ($timeout) {
    return {
        link: function ($scope, element, attrs) {
            $scope.$on('dataloaded', function () {
                $timeout(function () { // You might need this timeout to be sure its run after DOM render.
                    element.width()
                    element.height()
                }, 0, false);
            })
        }
    };
}]);

Olivér의 답변은 좋지만 문제가 있습니다. 이벤트를 방송하는 것을 잊으면 Javascript가 실행되지 않고 데이터가 변경될 수 있습니다.또 다른 솔루션은 다음과 같은 범위의 변경을 감시하는 것입니다.

var tradesInfo = TradesInfo.get({}, function(data) {
  console.log(data);
  $scope.profile = data.profile;
  // ...
});


directive('heightStuff', ['$timeout',
  function($timeout) {
    return {
      scope: {
        myData: '='
      },
      link: function($scope, element, attrs) {
        $scope.$watch('myData', function() {
          $timeout(function() { // You might need this timeout to be sure its run after DOM render.
            element.width()
            element.height()
          }, 0, false);
        })
      }
    };
  }
]);
<div height-stuff my-data="profile"></div>

이렇게 하면 커스텀 이벤트 없이 데이터가 변경될 마다 Javascript 함수가 호출됩니다.

JQuery를 사용하기 위한 또 다른 제안입니다.지시로 생성된 그리드에 대해 이 문제를 해결해야 했습니다.그리드의 특정 행으로 스크롤하려고 했습니다.디렉티브에서 부모 컨트롤러로 브로드캐스트하려면 $emit을 사용합니다.

컨트롤러 내:

    ['$timeout',function($timeout){
...
 $scope.$on('dataloaded', function () {
            $timeout(function () { // You might need this timeout to be sure its run after DOM render.
                $scope.scrollToPosition();
            }, 0, false);
        });
        $scope.scrollToPosition = function () {
            var rowpos = $('#row_' + $scope.selectedActionID, "#runGrid").position();
            var tablepost = $('table', "#runGrid").position();
            $('#runGrid').scrollTop(rowpos.top - tablepost.top);
        }

지시로

.directive('runGrid',['$timeout', function ($timeout) {
        // This directive generates the grip of data
        return {
            restrict: 'E',  //DOM Element
            scope: {    //define isolated scope
                list: '=',   //use the parent object
                selected: "="
            },

            templateUrl: '/CampaignFlow/StaticContent/Runs/run.grid.0.0.0.0.htm',  //HTML template URL

            controller: ['$scope', function ($scope) {  //the directive private controller, whith its private scope
                //$scope.statusList = [{ data_1: 11, data_2: 12 }, { data_1: 21, data_2: 22 }, { data_1: 31, data_2: 32 }];
                //Controller contains sort functionallity

                $scope.sort = { column: null, direction: 1 }
                $scope.column = null;
                $scope.direction = "asc";
                $scope.sortColumn = function (id) {
                    if(id!=$scope.column) {
                        $scope.column = id;
                        $scope.direction = "asc";
                    } else {
                        $scope.column = null;
                    }
                }
                $scope.toggleDir = function () {
                    $scope.direction = ($scope.direction == "asc") ? "desc" : "asc";
                }
               $scope.$emit('dataloaded');
            }]


        };
    }])

다음은 그리드 디렉티브html 템플릿의 일부입니다.

 <div style="overflow-y:auto;height: 200px;" id="runGrid">
            <table class="table table-striped" style="table-layout:fixed">
           <tbody>
                <tr  ng-repeat="status in list" id="row_{{status.action_id}}" ng-class="(status.action_id==selected)?'selected':''">
                    <td>

목록과 선택된 파라미터는 디렉티브를 사용하는html에서 삽입됩니다.

<run-grid list="list" selected="selectedActionID"></run-grid>

위의 답변은 ngRepeat이 완료된 후 실행하는 데 필요한 코드는 각도 코드이며, 이 경우 위의 모든 답변은 다른 답변보다 더 일반적이고 훌륭하고 단순한 솔루션을 제공합니다.다이제스트 라이프 사이클 스테이지가 중요한 경우, 그것에 관한 Ben Nadel의 블로그를 참조할 수 있습니다.단, $eval 대신 $parse를 사용하는 것은 예외입니다.

그러나 제 경험상 OP가 기술한 바와 같이 최종 컴파일된 DOM 상에서 보통 jQuery 플러그인 또는 메서드를 실행하고 있습니다.이 경우 가장 간단한 해결책은 directive를 만드는 것입니다.setTimeout, 그 이후로setTimeout함수는 브라우저 큐의 끝에 푸시됩니다.이것은 항상 모든 것이 각진 상태로 완료된 직후입니다.보통은ng-repeat부모 postLinking 기능 이후에도 계속됩니다.

angular.module('myApp', [])
.directive('pluginNameOrWhatever', function() {
  return function(scope, element, attrs) {        
    setTimeout(function doWork(){
      //jquery code and plugins
    }, 0);        
  };
});

$timeout을 사용하지 않는 이유는 전혀 불필요한 또 다른 다이제스트 사이클이 발생하기 때문입니다.

편집:

다이제스트를 일으키지 않고 $drzaus를 사용하는 방법에 대한 링크의 thanx to drzaus http://www.codelord.net/2015/10/14/angular-nitpicking-differences-between-timeout-and-settimeout/

언급URL : https://stackoverflow.com/questions/16935766/run-jquery-code-after-angularjs-completes-rendering-html

반응형