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

Pat*_*zlo 125 typescript viewchild angular angular8

我应该如何配置新的Angular 8视图子级?

@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;
Run Code Online (Sandbox Code Playgroud)

@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;
Run Code Online (Sandbox Code Playgroud)

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

Pie*_*Duc 134

在大多数情况下,您将需要使用{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;
}
Run Code Online (Sandbox Code Playgroud)

static: false会是在角9.读默认的备用行为更加这里这里

{ static: true }引入了该选项以支持动态创建嵌入式视图。当您动态创建视图并希望访问时TemplateRef,您将无法执行操作,ngAfterViewInit因为这会导致ExpressionHasChangedAfterChecked错误。将static标志设置为true将在ngOnInit中创建您的视图。

不过:

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

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

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

有关迁移指南以及更多相关信息,可以在此处此处进行检查

静态查询和动态查询有什么区别?

@ViewChild()和@ContentChild()查询的静态选项确定查询结果何时可用。

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

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

  • 我无法访问 childView 的实例。它一直说未定义。 (2认同)
  • @MinhNghĩa 如果将整个组件嵌套在组件模板之外,则可以使用“{ static: true }”,但如果没有直接需要访问“ngOnInit”内的ViewChild,则应该使用“{”静态:假}`。 (2认同)

dav*_*688 40

因此,根据经验,您可以执行以下操作:

  • { static: true }要访问ViewChildin 时需要设置ngOnInit

  • { static: false }只能在中访问ngAfterViewInit。当*ngIf模板中的元素上具有结构性指令(即)时,这也是您要追求的目标。

  • 注意:在 Angular 9 中,static 标志默认为 false,因此“任何 {static: false} 标志都可以安全地删除”。文档:https://angular.io/guide/static-query-migration (4认同)

Pav*_*van 26

静态属性告知 Angular 我们孩子的可用性

例如:如果 static 设置为true,我们会通知 Angular 我们的子组件从一开始就可以在页面上使用(这意味着它不依赖于 *ngIf、页面绑定、API 调用等),因此 Angular 在最早的生命周期中会查找它钩子(ngOnInit)并且不再寻找它

如果我们将 static 设置为false,我们会通知 Angular 我们的子组件依赖于某些条件指令,因此 Angular 会尝试在每个更改检测周期后查找我们的子组件,如果可用,我们可以在 ngAfterViewInit() 生命周期挂钩中访问它


Sac*_*pta 16

从角度文档

静态 -是否在更改检测运行之前解析查询结果(即仅返回静态结果)。如果未提供此选项,则编译器将退回到其默认行为,即使用查询结果来确定查询解析的时间。如果任何查询结果在嵌套视图中(例如* ngIf),则将在运行更改检测后解决查询。否则,将在运行更改检测之前解决该问题。

static:true如果孩子不依赖任何条件,使用它可能是一个更好的主意。如果元素的可见性发生变化,则static:false可能会得到更好的结果。

PS:由于它是一项新功能,我们可能需要运行性能基准。

编辑

如@Massimiliano Sartoretto所述,github commit可能会为您提供更多见解。

  • 我会在此功能后面添加官方动机https://github.com/angular/angular/pull/28810 (3认同)