Angular 2에서 구성 요소를 다시 렌더링하는 방법은 무엇입니까? Redux로 작업하는 디버그 목적으로 구성 요소가 다시 렌더링되도록 강제하고 싶습니다. 가능합니까?
Angular 2에서 구성 요소를 다시 렌더링하는 방법은 무엇입니까? Redux로 작업하는 디버그 목적으로 구성 요소가 다시 렌더링되도록 강제하고 싶습니다. 가능합니까?
답변:
변경 감지 후 렌더링이 수행됩니다. 변경된 구성 요소 속성 값이 DOM으로 전파되도록 변경 감지를 강제 실행하려면 (브라우저가 해당 변경 사항을보기에서 렌더링 함) 다음과 같은 옵션이 있습니다.
$rootScope.$digest()
즉, 전체 컴포넌트 트리를 확인하십시오$rootScope.$apply(callback)
- 즉, 각 2 구역 내부의 콜백 함수를 평가합니다. 나는 이것이 콜백 함수를 실행 한 후 전체 구성 요소 트리를 확인하게된다고 확신하지는 않습니다.$scope.$digest()
-즉,이 구성 요소와 그 하위 만 확인당신은 가져 주입 한 후해야합니다 ApplicationRef
, NgZone
또는 ChangeDetectorRef
구성 요소에.
특정 시나리오의 경우 단일 구성 요소 만 변경된 경우 마지막 옵션을 사용하는 것이 좋습니다.
this is the first time I am facing an update not working in ng2
. 변경 감지 전략이 기본값이므로 변경 감지 전략을 망쳐 놓지 않았습니다.
this
는 POST 콜백에서 올바른 컨텍스트를 사용하지 않는 것 입니다.
pure:false
. 작동하지만 사용 사례에 비해 너무 비쌉니다 (비효율적).
tx, 내가 필요한 해결 방법을 찾았습니다.
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
zone.run을 실행하면 구성 요소가 다시 렌더링됩니다.
ChangeDetectorRef 접근 방식
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
export class MyComponent {
constructor(private cdr: ChangeDetectorRef) { }
selected(item: any) {
if (item == 'Department')
this.isDepartment = true;
else
this.isDepartment = false;
this.cdr.detectChanges();
}
}
* ngIf를 사용하여 구성 요소를 강제로 다시로드합니다.
컨테이너 내부의 모든 구성 요소는 전체 수명주기 후크로 돌아갑니다.
템플릿에서 :
<ng-container *ngIf="_reload">
components here
</ng-container>
그런 다음 ts 파일에서 :
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
setTimeout()
. 이제는 간단하고 가벼운 솔루션으로 작업하고 있습니다!
다른 답변은 구성 요소의 뷰를 업데이트하는 변경 감지주기를 트리거하는 솔루션을 제공합니다 (전체 다시 렌더링과 동일하지 않음).
전체 사용하여 수행 할 수 있습니다 파괴하고 구성 요소 (보기 모든 라이프 사이클 후크를 호출하고 재건을) 다시 초기화 것이다, 재 렌더링 ng-template
, ng-container
및 ViewContainerRef
다음과 같은 방법으로 :
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
다음 구성 요소 모두에 대한 참조를 가지고 #outlet
와 #content
우리는 출구 '내용을 취소하고 하위 구성 요소의 다른 인스턴스를 삽입 할 수 있습니다 :
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
또한 초기 내용은 AfterContentInit
후크에 삽입해야합니다 .
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
전체 작업 솔루션은 https://stackblitz.com/edit/angular-component-rerender 에서 찾을 수 있습니다 .
ChangeDetectorRef.detectChanges()
일반적으로 가장 집중적 인 방법입니다. ApplicationRef.tick()
일반적으로 슬레지 해머 접근 방식이 너무 많습니다.
을 사용하려면 ChangeDetectorRef.detectChanges()
구성 요소 상단에이 항목이 필요합니다.
import { ChangeDetectorRef } from '@angular/core';
... 일반적으로 생성자에 다음과 같이 삽입하면 별칭이 지정됩니다.
constructor( private cdr: ChangeDetectorRef ) { ... }
그런 다음 적절한 장소에서 에서 다음과 같이 호출합니다.
this.cdr.detectChanges();
당신이 전화하는 곳ChangeDetectorRef.detectChanges()
은 매우 중요 할 수 있습니다. 당신은 할 필요가 완전히 라이프 사이클을 이해하고 정확히 응용 프로그램 기능 및 해당 구성 요소를 렌더링하는 방법. 숙제를 완전히하고 Angular 라이프 사이클을 이해하는 것을 대체 할 수있는 것은 없습니다. 그런 다음, 일단 이해하면 ChangeDetectorRef.detectChanges()
적절하게 사용할 수 있습니다 (때로는 사용 위치를 이해하기가 쉽고 때로는 복잡 할 수도 있음).