각도 2: ngFor가 완료되면 콜백
Angular 1에 사용할 커스텀 지시문("반복 가능")을 작성했습니다.ng-repeat
반복이 완료되면 콜백 방식을 호출하려면 다음 절차를 수행합니다.
if ($scope.$last === true)
{
$timeout(() =>
{
$scope.$parent.$parent.$eval(someCallbackMethod);
});
}
마크업에서의 사용:
<li ng-repeat="item in vm.Items track by item.Identifier"
repeater-ready="vm.CallThisWhenNgRepeatHasFinished()">
어떻게 하면 같은 기능을 얻을 수 있을까요?ngFor
앵귤러 2에?
이 목적으로 @ViewChildren을 사용할 수 있습니다.
@Component({
selector: 'my-app',
template: `
<ul *ngIf="!isHidden">
<li #allTheseThings *ngFor="let i of items; let last = last">{{i}}</li>
</ul>
<br>
<button (click)="items.push('another')">Add Another</button>
<button (click)="isHidden = !isHidden">{{isHidden ? 'Show' : 'Hide'}}</button>
`,
})
export class App {
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
@ViewChildren('allTheseThings') things: QueryList<any>;
ngAfterViewInit() {
this.things.changes.subscribe(t => {
this.ngForRendred();
})
}
ngForRendred() {
console.log('NgFor is Rendered');
}
}
오리지널 답변은 이쪽 https://stackoverflow.com/a/37088348/5700401
다음과 같은 것을 사용할 수 있습니다(ng로컬 변수의 경우).
<li *ngFor="#item in Items; #last = last" [ready]="last ? false : true">
그런 다음 설정기를 사용하여 입력 속성 변경을 가로챌 수 있습니다.
@Input()
set ready(isReady: boolean) {
if (isReady) someCallbackMethod();
}
저는 Typescript를 사용하여 Angular2에서 작업합니다.
<li *ngFor="let item in Items; let last = last">
...
<span *ngIf="last">{{ngForCallback()}}</span>
</li>
그러면 이 기능을 사용하여 처리할 수 있습니다.
public ngForCallback() {
...
}
해결책은 아주 사소한 것이다.언제인지 알고 싶다면ngFor
는 브라우저 창에 모든 DOM 요소 인쇄를 완료하고 다음 절차를 수행합니다.
1. 플레이스 홀더 추가
인쇄할 컨텐츠의 자리 표시자를 추가합니다.
<div *ngIf="!contentPrinted">Rendering content...</div>
2. 용기 추가
컨테이너를 만듭니다.display: none
내용을 확인합니다.모든 아이템이 인쇄되면display: block
.contentPrinted
컴포넌트 플래그 속성입니다.기본값은 입니다.false
:
<ul [class.visible]="contentPrinted"> ...items </ul>
3. 콜백 메서드를 작성하다
더하다onContentPrinted()
컴포넌트에 접속할 수 있습니다.이 컴포넌트는 다음 시간 후에 자동으로ngFor
완료:
onContentPrinted() { this.contentPrinted = true; this.changeDetector.detectChanges(); }
그리고 잊지 말고ChangeDetectorRef
피하다ExpressionChangedAfterItHasBeenCheckedError
.
4. ngFor 사용last
가치
선언하다last
에 따라 변동하다.ngFor
실내에서 사용하다li
이 항목이 마지막 항목일 때 메서드를 실행하려면:
<li *ngFor="let item of items; let last = last"> ... <ng-container *ngIf="last && !contentPrinted"> {{ onContentPrinted() }} </ng-container> <li>
- 사용하다
contentPrinted
실행할 구성 요소 플래그 속성onContentPrinted()
딱 한 번만. - 사용하다
ng-container
레이아웃에 영향을 주지 않도록 합니다.
[ready] 대신 다음과 같이 [attr.ready]를 사용합니다.
<li *ngFor="#항목, #last = last" [attr.ready]="last ? false : true">
RC3에서 인정된 답변이 작동하지 않는 것을 발견했습니다.하지만, 저는 이 문제를 해결할 방법을 찾았습니다.MDL componentHandler를 실행하여 컴포넌트를 업그레이드하려면 ngFor가 언제 완료되었는지 알아야 합니다.
우선 지시가 필요합니다.
업그레이드 컴포넌트.directive.ts
import { Directive, ElementRef, Input } from '@angular/core';
declare var componentHandler : any;
@Directive({ selector: '[upgrade-components]' })
export class UpgradeComponentsDirective{
@Input('upgrade-components')
set upgradeComponents(upgrade : boolean){
if(upgrade) componentHandler.upgradeAllRegistered();
}
}
다음으로 컴포넌트로 Import하여 디렉티브에 추가합니다.
import {UpgradeComponentsDirective} from './upgradeComponents.directive';
@Component({
templateUrl: 'templates/mytemplate.html',
directives: [UpgradeComponentsDirective]
})
이제 HTML에서 "upgrade-components" 속성을 true로 설정합니다.
<div *ngFor='let item of items;let last=last' [upgrade-components]="last ? true : false">
이 Atribut이 true로 설정되면 @Input() 선언으로 메서드가 실행됩니다.이 경우 componentHandler.upgradeAllRegistered()가 실행됩니다.단, 원하는 대로 사용할 수 있습니다.ngFor 문의 '마지막' 속성에 바인딩함으로써 종료 시 실행됩니다.
[ attr . upgrade - components ]는 현재 bonafide 디렉티브이기 때문에 네이티브아트리뷰트가 아닌 경우에도 사용할 필요가 없습니다.
저는 이 문제에 대해 데모를 쓰고 있습니다.이 이론은 받아들여진 대답에 기초하고 있지만, 이 대답은 완전하지 않다.li
를 받아들일 수 있는 커스텀 컴포넌트여야 합니다.ready
discloss.discloss.
새로운 컴포넌트를 정의합니다.
'@angular/core'에서 {Component, Input, OnInit} 가져오기;
@Component({
selector: 'app-li-ready',
templateUrl: './li-ready.component.html',
styleUrls: ['./li-ready.component.css']
})
export class LiReadyComponent implements OnInit {
items: string[] = [];
@Input() item;
constructor() { }
ngOnInit(): void {
console.log('LiReadyComponent');
}
@Input()
set ready(isReady: boolean) {
if (isReady) {
console.log('===isReady!');
}
}
}
템플릿
{{item}}
앱 구성 요소에서의 사용
<app-li-ready *ngFor="let item of items; let last1 = last;" [ready]="last1" [item]="item"></app-li-ready>
콘솔에 로그가 표시되고 모든 항목 문자열이 인쇄된 후 isReady가 인쇄됩니다.
ngFor가 어떻게 후드 아래에서 요소를 렌더링하는지 자세히 알아보지 못했습니다.그러나 관찰 결과, 반복되는 각 항목마다 두 번 이상 식을 평가하는 경향이 있는 것으로 나타났습니다.
이로 인해 ngFor 'last' 변수를 체크할 때 이루어지는 모든 타입스크립트 메서드 호출이 여러 번 트리거될 수 있습니다.
ng에 의해 타이프스크립트 메서드에 대한1개의 콜을 보증하려면 ngFor가 후드 아래에서 수행하는 여러 표현 재평가로부터 작은 보호를 추가해야 합니다.
(지시를 통해) 이를 수행하는 한 가지 방법은 다음과 같습니다.
지시 코드
import { Directive, OnDestroy, Input, AfterViewInit } from '@angular/core';
@Directive({
selector: '[callback]'
})
export class CallbackDirective implements AfterViewInit, OnDestroy {
is_init:boolean = false;
called:boolean = false;
@Input('callback') callback:()=>any;
constructor() { }
ngAfterViewInit():void{
this.is_init = true;
}
ngOnDestroy():void {
this.is_init = false;
this.called = false;
}
@Input('callback-condition')
set condition(value: any) {
if (value==false || this.called) return;
// in case callback-condition is set prior ngAfterViewInit is called
if (!this.is_init) {
setTimeout(()=>this.condition = value, 50);
return;
}
if (this.callback) {
this.callback();
this.called = true;
}
else console.error("callback is null");
}
}
모듈에서 위의 디렉티브를 선언한 후(그 방법을 알고 있지 않은 경우 물어보고 코드 스니펫으로 업데이트하기를 희망합니다), ngFor에서 디렉티브를 사용하는 방법은 다음과 같습니다.
<li *ngFor="let item of some_list;let last = last;" [callback]="doSomething" [callback-condition]="last">{{item}}</li>
'doSomething'은 typeScript 파일의 메서드 이름입니다.ngFor가 항목을 통해 반복 작업을 마쳤을 때 호출합니다.
주의: 'doSomething'에는 괄호 '(')가 없습니다.이것은 타이프스크립트 메서드에 대한 참조를 전달했을 뿐 실제로는 여기서 호출하지 않기 때문입니다.
마지막으로 'doSomething' 메서드는 다음과 같습니다.
public doSomething=()=> {
console.log("triggered from the directive's parent component when ngFor finishes iterating");
}
언급URL : https://stackoverflow.com/questions/35819264/angular-2-callback-when-ngfor-has-finished
'programing' 카테고리의 다른 글
쉼표로 구분된 링크 목록 렌더링 (0) | 2023.03.26 |
---|---|
ReactJS 오류 경고 (0) | 2023.03.26 |
키 배열과 값 배열을 JavaScript에서 개체로 병합 (0) | 2023.03.26 |
카르마 장치 테스트 중 이미지에 대한 경고 404개를 수정하는 방법 (0) | 2023.03.26 |
경고:Firebase JS SDK의 개발 빌드를 사용하고 있는 것 같습니다. (0) | 2023.03.26 |