내 구성 요소 중 하나 내에서 변경 감지가 너무 자주 실행되는 문제가 trackBy
있어서 ngFor
지시문에 대한 옵션 을 사용하려고합니다 .
읽기를 통해 Angular는 trackyBy
다음에 변경 감지가 실행될 때 diff 함수 에서 반환 된 값을 사용한다는 것을 이해합니다 . 내 필요에 맞는지 확인하고 더 잘 이해하기 위해 놀이터를 만들었습니다. 그것을 trackyBy
사용할 때 정의되지 않은 반환에 사용 하는 함수 의 반환 값을 설정 했지만 여전히 원하는 결과를 얻었습니다.
TS :
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
styleUrls: ['./app.component.scss'],
templateUrl: './app.component.html',
})
export class AppComponent {
collection;
constructor() {
this.collection = [{id: 1, value: 0}, {id: 2, value: 0}, {id: 3, value: 0}];
}
getItems() {
this.collection = this.getItemsFromServer();
}
getItemsFromServer() {
return [{id: 5, value: 0}, {id: 2, value: 0}, {id: 3, value: 3}, {id: 4, value: 4}];
}
trackByFn(index, item) {
return undefined;
}
}
HTML :
<ul>
<li *ngFor="let item of collection;trackBy: trackByFn">{{ item.id }}hello {{item.value}}</li>
</ul>
<button (click)="getItems()">Refresh items</button>
첫 번째 클릭의 결과는 배열의 인덱스 1을 제외한 모든 항목이 새 값 또는 ID로 다시 렌더링됩니다. 두 번째 클릭에서 어떤 항목도 개체 내에서 아무것도 변경되지 않습니다.
그래서 내 질문은 왜 trackBy
함수 의 반환 값에 고유 ID를 사용 합니까? 내가 놓친 것이 있어야하며 아직 보지 못하는 방식으로 내 애플리케이션에 영향을 미치기를 원하지 않습니다.
공식적인 대답은 trackBy
동일한 식별자를 가진 객체의 새 인스턴스에 대해 DOM에서 요소를 다시 만들지 않기 위해 사용한다는 것 입니다.
겉보기에, 당신의 설정은 당신이 반환 ngFor
하는 undefined
값을 무시하고 trackByFn
새로운 인스턴스가 모델에 나타날 때 DOM 요소를 다시 만드는 것만 이 아니라는 것을 증명하지 않습니다 .
기존 객체와 동일한 ID를 가진 새 항목은 다른 속성이 변경되었을 수 있으므로 사용 (또는 오용) 여부에 관계없이 HTML이 정확할 것으로 기대할 수 있습니다 trackBy
.
나는 소스 코드 포크를 제외하고 나는, 당신의 코드를 사용하여 테스트 환경을 만들어 *ngFor
나가 내부에 무슨 일 추적하기 위해 내 자신의 기록을 추가 할 수 있도록를 *ngFor
.
세 가지 시나리오를 테스트했습니다.
A) trackByFn
고유 ID를 반환합니다.
B) trackByFn
반환undefined
C) 사용하지 않습니다 trackBy
다음 단계에 대해 각 시나리오에서 어떤 일이 발생하는지 추적했습니다.
"순수한"테스트를 위해 각 단계에서 개체의 새 인스턴스를 할당했습니다.
1. 목록 만들기
세 가지 시나리오 모두 동일합니다. 목록의 각 항목에 대해 DOM 요소가 생성됩니다.
2. 일부 목록 데이터를 부분적으로 교체
A) 제거 된 항목에 대한 DOM 요소를 제거하고 새 항목에 대한 새 DOM 요소를 만듭니다. 모든 요소가 업데이트됩니다.
B) 원래 배열의 경계를 벗어난 인덱스가있는 항목에 대한 새 DOM 요소를 만듭니다. 모든 요소가 업데이트됩니다.
C) 모든 DOM 요소를 다시 만듭니다.
3. 정렬 목록
A) 위치를 이동 한 DOM 요소 이동
B) 위치를 이동 한 DOM 요소 업데이트
C) 모든 DOM 요소를 다시 만듭니다.
4. 목록 데이터 재설정
A) 제거 된 항목에 대한 DOM 요소를 제거하고 새 항목에 대한 새 DOM 요소를 만듭니다. 모든 요소가 업데이트됩니다 (시나리오 2와 동일).
B) 제거 된 항목에 대한 DOM 요소를 제거합니다. 모든 요소가 업데이트됩니다.
C) 모든 DOM 요소를 다시 만듭니다.
이러한 테스트는 개체의 새 인스턴스를 사용하여 수행되었습니다. *ngFor
객체 참조를 재사용하는 경우 더 효율적입니다.
trackBy
매우 변동적인 목록이있는 경우 DOM 조작 측면에서 사용하는 것이 더 효율적입니다.
놀라운 결과
내 테스트에서 귀하의 예제는에서 고유 식별자를 반환 할 때보 다 DOM 조작이 덜한 것으로 보입니다 trackByFn
. 3 개의 항목을 3 개의 새 항목으로 바꾸면 메서드는 DOM 조작을 수행하지 않고 "적절한"방식과 동일한 업데이트 메서드를 계속 실행합니다. "proper"메소드는 원래 3 개의 DOM 요소를 제거하고 3 개의 새 DOM 요소를 추가합니다.
이는 trackByFn
예상치 못한 결과없이 상수 값을 반환 하는를 제공 할 수 있음을 의미합니다 . 소스 코드를 훑어보고 놀아 보면 이것이 어떻게 문제인지 알 수 없습니다 (귀하의 코드를 보는 다른 사람들을 혼란스럽게하는 것 외에는 제외).
이것은 이전 DOM 요소를 재사용하는 것이 잘 작동하는 것처럼 보일 때 기본 구현이 모든 DOM 요소를 다시 만들어야하는 이유를 궁금하게 만듭니다. 고려하지 않은 몇 가지 사례가있을 것입니다. 듣고 싶습니다.
데모 : https://stackblitz.com/edit/angular-anejhw
이것은 결정적인 대답이 아니라 약간의 "재미있는"연구 과제로 바뀌었지만, 유용하게 사용되기를 바랍니다. 에서 상수 값을 반환하는 trackByFn
것이 가장 성능이 좋은 옵션 인 것처럼 보였지만 프로덕션 코드에서이 접근 방식을 사용하는 것은 여전히 주저합니다. 지금은 모든 경우에 작동한다고해도 어느 시점에서 버그로 "고정"된다면 놀라지 않을 것입니다.
ngForOf
소스 코드 : https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_for_of.ts
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다