小编典典

我应该如何在 Angular 8 中为 @ViewChild 使用新的静态选项?

all

我应该如何配置新的 Angular 8 view child?

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

对比

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

哪个更好?我什么时候应该使用static:truevs static:false


阅读 143

收藏
2022-04-26

共1个答案

小编典典

在大多数情况下,您会想要使用{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将是 Angular 9
中的默认后备行为。在此处此处阅读更多信息

引入该{ static: true }选项是为了支持动态创建嵌入式视图。当您动态创建视图并想要访问
TemplateRef,您将无法这样做,ngAfterViewInit因为它会导致ExpressionHasChangedAfterChecked错误。将静态标志设置为
true 将在 ngOnInit 中创建您的视图。

尽管如此:

在大多数其他情况下,最佳做法是使用{static: false}.

请注意,尽管该{ static: false }选项将在 Angular 9 中设为默认值。这意味着不再需要设置静态标志,除非您想使用该static: true选项。

您可以使用 angular cling update命令自动升级您当前的代码库。

有关迁移指南甚至更多相关信息,您可以在此处此处查看

静态查询和动态查询有什么区别?@ViewChild() 和 @ContentChild() 查询的静态选项确定查询结果何时可用。

使用静态查询 (static: true),一旦创建了视图,查询就会解析,但在更改检测运行之前。但是,结果永远不会更新以反映视图的更改,例如对 ngIf
和 ngFor 块的更改。

对于动态查询(静态:false),查询分别在 @ViewChild() 和 @ContentChild() 的 ngAfterViewInit() 或
ngAfterContentInit() 之后解析。结果将根据您的视图的更改进行更新,例如对 ngIf 和 ngFor 块的更改。


using 的一个很好的用例static: true是,如果您要使用fromEvent绑定到模板中定义的元素。考虑以下模板:

<div [ngStyle]="thumbStyle$ | async" #thumb></div>

然后,您可以处理此元素上的事件,而无需使用订阅或初始化挂钩(如果您不想或不能使用角度事件绑定):

@Component({})
export class ThumbComponent {
  @ViewChild('thumb', { static: true })
  thumb?: ElementRef<HTMLElement>;

  readonly thumbStyle$ = defer(() => fromEvent(this.thumb, 'pointerdown').pipe(
    switchMap((startEvent) => fromEvent(document, 'pointermove', { passive: true })
    // transform to proper positioning
  ));
}

使用很重要defer。这将确保 observable
仅在订阅时才被解析。这将发生在ngAfterViewInit被触发之前,当async管道订阅它时。因为我们正在使用static: true,所以this.thumb已经填充。

2022-04-26