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

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

vs

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

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

推荐答案

在大多数情况下,你会希望使用{static: false}.这样设置将确保找到依赖于绑定解析的查询匹配(如 struct 指令*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中的默认回退行为.阅读更多herehere

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

然而:

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

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

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

有关迁移指南和有关这方面的更多信息,您可以查看herehere

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

对于静电查询(静电:TRUE),在创建视图之后、运行更改检测之前解析查询.但是,结果永远不会更新以反映对视图的更改,例如对ngIf和ngFor块的更改.

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


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

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

然后,无需使用订阅或init hook(如果不想或无法使用Angular 事件绑定),就可以处理该元素上的事件:

@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是很重要的.这将确保仅在订阅时才解析可观测对象.当async管道订阅ngAfterViewInit时,这将在ngAfterViewInit被触发之前发生.因为我们使用的是static: true,所以this.thumb已经装满了.

Angular相关问答推荐

从嵌套组件导航到命名路由中的顶级路由

如何在Angular模块中的forRoot中注入配置

Primeng 12Angular 12自定义库:错误符号字段集声明于...在编译保存后未从Primeng/fieldset中导出

如何动态呈现组件并以Angular 访问它们的方法?

带输入的单位测试Angular 分量.需要

是否可以将Angular 路由配置为在点击带有本地人力资源S的锚点时更新Angular 路由?

如何在ANGLING v17中使用鞋带样式组件?

茉莉花-模板中调用了如何判断角管

对Angular 为17的路径使用AuthGuard

Angular Signals 如何影响 RXJS Observables 以及在这种情况下变化检测会发生什么

VSCode / Angular 应用程序未完全启动

Angular14:支持旧版浏览器的官方方式是什么?

Angular 2 二传手与 ngOnChanges

使用 NPM 安装 Font Awesome 5

Springboot/Angular2 - 如何处理 HTML5 url?

如何使用Angular4通过元素ID设置焦点

Angular2 Base64 清理不安全的 URL 值

Angular Material2 主题 - 如何设置应用程序背景?

为什么 *ngIf 不适用于 ng-template?

如何使用formControlName和处理嵌套的formGroup?