[javascript] ng-repeat finish 이벤트

테이블이있는 div를 대상으로하는 jQuery 함수를 호출하고 싶습니다. 해당 테이블은로 채워집니다 ng-repeat.

내가 전화하면

$(document).ready()

결과가 없습니다.

또한

$scope.$on('$viewContentLoaded', myFunc);

도움이되지 않습니다.

ng-repeat 채우기가 완료된 직후 기능을 실행할 수있는 방법이 있습니까? custom 사용에 대한 조언을 읽었 directive지만 ng-repeat 및 div와 함께 사용하는 방법에 대한 실마리는 없습니다 …



답변

실제로 지시어를 사용해야하며 ng-Repeat 루프의 끝에 연결된 이벤트가 없습니다 (각 요소는 개별적으로 구성되며 자체 이벤트가 있기 때문에). 그러나 a) 지시문을 사용하는 것이 필요할 수 있습니다. b) “on ngRepeat finished”이벤트를 만드는 데 사용할 수있는 ng-Repeat 특정 속성이 몇 가지 있습니다.

특히, 전체 테이블에 이벤트를 스타일 지정 / 추가하는 것이 모든 ngRepeat 요소를 포함하는 지시문을 사용하여 수행 할 수 있습니다. 반면에 각 요소를 구체적으로 지정하려면 ngRepeat 내에서 지시문을 사용하면 각 요소가 작성된 후 각 요소에 대해 작동합니다.

그런 다음, 거기에있는 $index, $first, $middle$last속성은 트리거 이벤트에 사용할 수 있습니다. 따라서이 HTML의 경우 :

<div ng-controller="Ctrl" my-main-directive>
  <div ng-repeat="thing in things" my-repeat-directive>
    thing {{thing}}
  </div>
</div>

다음과 같은 지시문을 사용할 수 있습니다.

angular.module('myApp', [])
.directive('myRepeatDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('color','blue');
    if (scope.$last){
      window.alert("im the last!");
    }
  };
})
.directive('myMainDirective', function() {
  return function(scope, element, attrs) {
    angular.element(element).css('border','5px solid red');
  };
});

Plunker 에서 실제로 작동하는 것을 보십시오 . 그것이 도움이되기를 바랍니다!


답변

루프가 끝날 때 일부 코드를 실행하려면 추가 이벤트 처리가 필요하지 않은 약간 간단한 변형이 있습니다.

<div ng-controller="Ctrl">
  <div class="thing" ng-repeat="thing in things" my-post-repeat-directive>
    thing {{thing}}
  </div>
</div>
function Ctrl($scope) {
  $scope.things = [
    'A', 'B', 'C'
  ];
}

angular.module('myApp', [])
.directive('myPostRepeatDirective', function() {
  return function(scope, element, attrs) {
    if (scope.$last){
      // iteration is complete, do whatever post-processing
      // is necessary
      element.parent().css('border', '1px solid black');
    }
  };
});

라이브 데모를보십시오.


답변

지시어를 만들 필요는 없습니다. 특히 ng-repeat 완전한 이벤트 .

ng-init 당신을 위해 마술을 않습니다.

  <div ng-repeat="thing in things" ng-init="$last && finished()">

$last것을 확인한다finished 마지막 요소는 DOM에 렌더링 된 경우에만 트리거됩니다.

만드는 것을 잊지 마세요 $scope.finished이벤트 .

행복한 코딩 !!

편집 : 2016 년 10 월 23 일

finished배열에 항목이 없을 때 함수 를 호출하려는 경우 다음 해결 방법을 사용할 수 있습니다

<div style="display:none" ng-init="things.length < 1 && finished()"></div>
//or
<div ng-if="things.length > 0" ng-init="finished()"></div>

위의 라인을 상단에 추가하십시오. ng-repeat요소 . 배열에 값이 없는지 확인하고 그에 따라 함수를 호출합니다.

예 :

<div ng-if="things.length > 0" ng-init="finished()"></div>
<div ng-repeat="thing in things" ng-init="$last && finished()">


답변

다음은 true 일 때 지정된 함수를 호출하는 반복 완료 지시문입니다. 렌더링 된 요소에서 툴팁을 초기화하는 것과 같이 DOM 조작을 수행하기 전에 호출 된 함수가 interval = 0과 함께 $ timeout을 사용해야한다는 것을 알았습니다. jsFiddle : http://jsfiddle.net/tQw6w/

$ scope.layoutDone에서 $ timeout 줄을 주석 처리하고 “NOT CORRECT!”를 주석 해제하십시오. 툴팁의 차이점을 확인하십시오.

<ul>
    <li ng-repeat="feed in feedList" repeat-done="layoutDone()" ng-cloak>
    <a href="{{feed}}" title="view at {{feed | hostName}}" data-toggle="tooltip">{{feed | strip_http}}</a>
    </li>
</ul>

JS :

angular.module('Repeat_Demo', [])

    .directive('repeatDone', function() {
        return function(scope, element, attrs) {
            if (scope.$last) { // all are rendered
                scope.$eval(attrs.repeatDone);
            }
        }
    })

    .filter('strip_http', function() {
        return function(str) {
            var http = "http://";
            return (str.indexOf(http) == 0) ? str.substr(http.length) : str;
        }
    })

    .filter('hostName', function() {
        return function(str) {
            var urlParser = document.createElement('a');
            urlParser.href = str;
            return urlParser.hostname;
        }
    })

    .controller('AppCtrl', function($scope, $timeout) {

        $scope.feedList = [
            'http://feeds.feedburner.com/TEDTalks_video',
            'http://feeds.nationalgeographic.com/ng/photography/photo-of-the-day/',
            'http://sfbay.craigslist.org/eng/index.rss',
            'http://www.slate.com/blogs/trending.fulltext.all.10.rss',
            'http://feeds.current.com/homepage/en_US.rss',
            'http://feeds.current.com/items/popular.rss',
            'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'
        ];

        $scope.layoutDone = function() {
            //$('a[data-toggle="tooltip"]').tooltip(); // NOT CORRECT!
            $timeout(function() { $('a[data-toggle="tooltip"]').tooltip(); }, 0); // wait...
        }

    })


답변

여기 ng-init에는 사용자 지정 지시문이 필요없는 간단한 접근 방식이 있습니다. 그것은 페이지로드시 특정 항목으로 ng-repeated 항목의 div를 자동 스크롤 해야하는 특정 시나리오에서 나에게 효과적이었습니다. 따라서 스크롤 기능 ng-repeat은 DOM에 대한 렌더링이 완료 될 때까지 기다려야 실행 됩니다.

<div ng-controller="MyCtrl">
    <div ng-repeat="thing in things">
        thing: {{ thing }}
    </div>
    <div ng-init="fireEvent()"></div>
</div>

myModule.controller('MyCtrl', function($scope, $timeout){
    $scope.things = ['A', 'B', 'C'];

    $scope.fireEvent = function(){

        // This will only run after the ng-repeat has rendered its things to the DOM
        $timeout(function(){
            $scope.$broadcast('thingsRendered');
        }, 0);

    };
});

이것은 ng-repeat가 처음 렌더링 된 후 한 번만 호출해야하는 함수에만 유용합니다. ng-repeat 내용이 업데이트 될 때마다 함수를 호출 해야하는 경우이 스레드의 다른 답변 중 하나를 사용자 지정 지시문과 함께 사용해야합니다.


답변

Pavel의 답변을 보완 하면 더 읽기 쉽고 쉽게 이해할 수있는 것이 있습니다.

<ul>
    <li ng-repeat="item in items"
        ng-init="$last ? doSomething() : angular.noop()">{{item}}</li>
</ul>

angular.noop처음에 거기에 있다고 생각 합니까?

장점 :

이에 대한 지시문을 작성할 필요가 없습니다 …


답변

사용자 지정 지시문이 필요하지 않고 ngInitLodash의 debounce방법을 사용하여 조금 더 간단한 접근 방식 일 수 있습니다 .

제어 장치:

$scope.items = [1, 2, 3, 4];

$scope.refresh = _.debounce(function() {
    // Debounce has timeout and prevents multiple calls, so this will be called 
    // once the iteration finishes
    console.log('we are done');
}, 0);

주형:

<ul>
    <li ng-repeat="item in items" ng-init="refresh()">{{item}}</li>
</ul>

최신 정보

삼항 연산자를 사용하는 더 간단한 순수한 AngularJS 솔루션이 있습니다.

주형:

<ul>
    <li ng-repeat="item in items" ng-init="$last ? doSomething() : null">{{item}}</li>
</ul>

알고 있음을 수 ngInit의 사용은 사전 링크 컴파일 단계 – 자녀의 지시가 처리되기 전에, 즉 표현이 호출됩니다. 이것은 여전히 ​​비동기 처리가 필요할 수 있음을 의미합니다.