[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
처음에 거기에 있다고 생각 합니까?
장점 :
이에 대한 지시문을 작성할 필요가 없습니다 …
답변
사용자 지정 지시문이 필요하지 않고 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의 사용은 사전 링크 컴파일 단계 – 자녀의 지시가 처리되기 전에, 즉 표현이 호출됩니다. 이것은 여전히 비동기 처리가 필요할 수 있음을 의미합니다.