[angular] Angular 8에서 @ViewChild에 새로운 정적 옵션을 어떻게 사용해야합니까?

새로운 Angular 8 뷰 하위를 어떻게 구성해야합니까?

@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;

vs

@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;

어떤게 더 좋아? 언제 static:truevs를 사용해야 static:false합니까?



답변

대부분의 경우을 사용하려고합니다 {static: false}. 이와 같이 설정하면 구조적 지시문과 같은 바인딩 분석에 의존하는 쿼리 일치를 *ngIf, etc...찾을 수 있습니다.

사용시기의 예 static: false:

@Component({
  template: `
    <div *ngIf="showMe" #viewMe>Am I here?</div>
    <button (click)="showMe = !showMe"></button>
  `
})
export class ExampleComponent {
  @ViewChild('viewMe', { static: false })
  viewMe?: ElementRef<HTMLElement>;

  showMe = false;
}

static: false더 각도 9. 읽기의 기본 대체 동작 될 것입니다 여기여기에

{ static: true }옵션은 내장 된 뷰 생성을 지원하기 위해 도입되었습니다. 동적으로 뷰를 생성하고에 액세스하려고 하면 오류 가 발생 TemplateRef하므로이를 수행 할 수 없습니다 . 정적 플래그를 true로 설정하면 ngOnInit에서 뷰가 생성됩니다.ngAfterViewInitExpressionHasChangedAfterChecked

그렇지만:

대부분의 경우 가장 좋은 방법은을 사용하는 것 {static: false}입니다.

알고 생각해야합니다 { static: false }당신이 사용하려는 경우가 아니면 정적 플래그를 설정하면, 더 이상 필요하다는 것을 의미 옵션은 각도 9에 기본을 할 것이다 static: true옵션을 선택합니다.

angular cli ng update명령을 사용 하여 현재 코드베이스를 자동으로 업그레이드 할 수 있습니다 .

마이그레이션 안내서 및 이에 대한 자세한 정보는 여기여기를 확인 하십시오 .

정적 쿼리와 동적 쿼리의 차이점은 무엇입니까?

@ViewChild () 및 @ContentChild () 쿼리에 대한 정적 옵션은 쿼리 결과를 사용할 수있는시기를 결정합니다.

정적 쿼리 (정적 : true)를 사용하면 뷰가 생성 된 후 변경 감지가 실행되기 전에 쿼리가 해결됩니다. 그러나 결과는 ngIf 및 ngFor 블록의 변경과 같은보기 변경 사항을 반영하도록 업데이트되지 않습니다.

동적 쿼리 (정적 : false)를 사용하면 @ViewChild () 및 @ContentChild ()에 대해 ngAfterViewInit () 또는 ngAfterContentInit () 후에 각각 쿼리가 해결됩니다. ngIf 및 ngFor 블록 변경과 같은보기 변경에 대한 결과가 업데이트됩니다.


답변

따라서 경험적으로 다음을 수행 할 수 있습니다.

  • { static: true }당신이 액세스 할 때 요구 설정을 할 수 ViewChild있는가 ngOnInit.

  • { static: false }에서만 액세스 할 수 있습니다 ngAfterViewInit. 이것은 또한 *ngIf템플릿의 요소에 구조적 지시어 (예 :)가있을 때 가고 싶은 것입니다 .


답변

각도 문서에서

static- 변경 감지가 실행되기 전에 쿼리 결과를 해결할지 여부 (정적 결과 만 반환) 이 옵션을 제공하지 않으면 컴파일러는 쿼리 결과를 사용하여 쿼리 해결 타이밍을 결정하는 기본 동작으로 돌아갑니다. 쿼리 결과가 중첩 된 뷰 안에 있으면 (예 : * ngIf) 변경 감지가 실행 된 후 쿼리가 해결됩니다. 그렇지 않으면 변경 감지가 실행되기 전에 해결됩니다.

static:true아이가 어떤 조건에 의존하지 않는 경우 사용하는 것이 좋습니다 . 요소의 가시성이 변경되면 static:false더 나은 결과를 얻을 수 있습니다.

추신 : 새로운 기능이기 때문에 성능 벤치 마크를 실행해야 할 수도 있습니다.

편집하다

@Massimiliano Sartoretto가 언급했듯이 github commit 은 더 많은 통찰력을 줄 수 있습니다.


답변

Angular 8로 업그레이드 한 후 ngOnInit에서 ViewChild가 null이기 때문에 여기에 왔습니다.

정적 쿼리는 ngOnInit 전에 채워지고 동적 쿼리 (static : false)는 채워집니다. 다시 말해, static : false를 설정 한 후 ngOnInit에서 viewchild가 null 인 경우 static : true로 변경하거나 코드를 ngAfterViewInit로 이동하는 것을 고려해야합니다.

https://github.com/angular/angular/blob/master/packages/core/src/view/view.ts#L332-L336을 참조 하십시오.

다른 답변은 정확하며 그 이유를 설명합니다. ngIf 내부의 ViewChild 참조와 같은 구조적 지시문에 의존하는 쿼리는이 지시문의 조건이 해결 된 후 (예 : 변경 감지 후) 실행되어야합니다. 그러나 static : true를 안전하게 사용하여 중첩되지 않은 참조에 대해 ngOnInit 전에 쿼리를 해결할 수 있습니다. 이 특별한 사례는 null 예외라고 언급하면서 나에게 있었던 것처럼이 특수성을 만날 수있는 첫 번째 방법 일 수 있습니다.


답변

자식 @angular 5+ 토큰 두 인수보기 ( ‘local reference name’, static : false | true)

@ViewChild('nameInput', { static: false }) nameInputRef: ElementRef;

참과 거짓의 차이점을 알고 이것을 확인하십시오.

static-변경 감지가 실행되기 전에 쿼리 결과를 해결할지 여부 (정적 결과 만 반환) 이 옵션을 제공하지 않으면 컴파일러는 쿼리 결과를 사용하여 쿼리 해결 타이밍을 결정하는 기본 동작으로 돌아갑니다. 쿼리 결과가 중첩 된 뷰 안에 있으면 (예 : * ngIf) 변경 감지가 실행 된 후 쿼리가 해결됩니다. 그렇지 않으면 변경 감지가 실행되기 전에 해결됩니다.


답변

ng8에서 상위 구성 요소의 하위 구성 요소에 액세스 할시기를 수동으로 설정할 수 있습니다. static을 true로 설정하면 상위 컴포넌트가 onInit후크 의 컴포넌트 정의 만 가져옵니다 . 예 :

 // You got a childComponent which has a ngIf/for tag
ngOnInit(){
  console.log(this.childComponent);
}

ngAfterViewInit(){
  console.log(this.childComponent);
}

static이 false 인 경우 ngAfterViewInit (), ngOnInit ()의 정의 만 정의되지 않습니다.


답변