답변:
실제로 지시어를 사용해야하며 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');
};
});
루프가 끝날 때 일부 코드를 실행하려면 추가 이벤트 처리가 필요하지 않은 약간 간단한 변형이 있습니다.
<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
처음에 거기에 있다고 생각 합니까?
장점 :
이에 대한 지시문을 작성할 필요가 없습니다 ...
ng-init="$last && doSomething( )"
사용자 지정 지시문이 필요하지 않고 ngInit
Lodash의 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의 사용은 사전 링크 컴파일 단계 - 자녀의 지시가 처리되기 전에, 즉 표현이 호출됩니다. 이것은 여전히 비동기 처리가 필요할 수 있음을 의미합니다.
ng-init="$last ? refresh() : false"
하면 효과가 있습니다. 그리고 그것은 Lodash를 요구하지도 않습니다.
scope.$last
변수를 확인 하여 트리거를 랩으로 래핑 할 때 필요할 수도 있습니다 setTimeout(someFn, 0)
. A setTimeout 0
는 자바 스크립트에서 허용되는 기술이며 directive
올바르게 실행 하는 것이 필수적이었습니다 .
이것은 선언적 구문과 격리 범위 ( 요소 지시어를 사용하는 것이 좋습니다. 주요 차이점은 다음과 같습니다 scope.$parent.$last
..
angular.module('myApp', [])
.directive('myRepeatDirective', function() {
return {
restrict: 'E',
scope: {
someAttr: '='
},
link: function(scope, element, attrs) {
angular.element(element).css('color','blue');
if (scope.$parent.$last){
window.alert("im the last!");
}
}
};
});
나는 이렇게했다.
지시문 작성
function finRepeat() {
return function(scope, element, attrs) {
if (scope.$last){
// Here is where already executes the jquery
$(document).ready(function(){
$('.materialboxed').materialbox();
$('.tooltipped').tooltip({delay: 50});
});
}
}
}
angular
.module("app")
.directive("finRepeat", finRepeat);
이 ng-repeat가있는 라벨에 추가 한 후
<ul>
<li ng-repeat="(key, value) in data" fin-repeat> {{ value }} </li>
</ul>
그리고 그 준비가 ng-repeat의 끝에서 실행될 것입니다.
위의 답변은 ngRepeat이 완료 된 후 실행하는 데 필요한 코드가 각도 코드이므로 다른 답변을 추가하고 싶습니다.이 경우 위의 모든 답변은 다른 것보다 더 일반적이고 훌륭하고 간단한 솔루션을 제공합니다. 중요한 다이제스트 수명주기 단계를 살펴보면 Ben Nadel의 블로그를 인 경우 $ eval 대신 $ parse를 사용하는 것을 제외 .
그러나 내 경험상 OP 상태에서 일반적으로 finnaly 컴파일 된 DOM에서 일부 JQuery 플러그인 또는 메소드를 실행합니다.이 경우 setTimeout 함수가 푸시되기 때문에 가장 간단한 해결책은 setTimeout으로 지시문을 작성하는 것입니다. 브라우저 대기열의 끝까지 모든 것이 각도로 완료 된 직후 항상, 일반적으로 ngReapet은 부모의 postLinking 함수 후에 계속됩니다.
angular.module('myApp', [])
.directive('pluginNameOrWhatever', function() {
return function(scope, element, attrs) {
setTimeout(function doWork(){
//jquery code and plugins
}, 0);
};
});
이 경우 $ timeout을 사용하지 않는 이유를 궁금해하는 사람에게는 완전히 불필요한 다른 다이제스트주기가 발생합니다.
나는 여기에서 잘 연습 된 답변을 찾았 지만 여전히 지연을 추가해야했습니다.
다음 지시문을 작성하십시오.
angular.module('MyApp').directive('emitLastRepeaterElement', function() {
return function(scope) {
if (scope.$last){
scope.$emit('LastRepeaterElement');
}
}; });
다음과 같이 속성으로 repeater에 추가하십시오.
<div ng-repeat="item in items" emit-last-repeater-element></div>
Radu에 따르면,
$scope.eventoSelecionado.internamento_evolucoes.forEach(ie => {mycode});
나를 위해 작동하지만 여전히 setTimeout을 추가해야합니다
$scope.eventoSelecionado.internamento_evolucoes.forEach(ie => {
setTimeout(function() {
mycode
}, 100); });
클래스 이름을 변경하여 다르게 렌더링되도록하려면 아래 코드에서 트릭을 수행하십시오.
<div>
<div ng-show="loginsuccess" ng-repeat="i in itemList">
<div id="{{i.status}}" class="{{i.status}}">
<div class="listitems">{{i.item}}</div>
<div class="listitems">{{i.qty}}</div>
<div class="listitems">{{i.date}}</div>
<div class="listbutton">
<button ng-click="UpdateStatus(i.$id)" class="btn"><span>Done</span></button>
<button ng-click="changeClass()" class="btn"><span>Remove</span></button>
</div>
<hr>
</div>
이 코드는 쇼핑 목록에 쇼핑 항목을 Strick trough 글꼴로 렌더링 해야하는 비슷한 요구 사항이있을 때 효과적이었습니다.
myMainDirective
'코드는 루프의 종료 후 실행 s는? 부모 div의 스크롤 막대를 업데이트해야합니다.