在大多数情况下,你会希望使用{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中的默认回退行为.阅读更多here和here
引入{ static: true }
选项是为了支持动态创建嵌入式视图.当您动态创建视图并希望访问TemplateRef
时,您将无法在ngAfterViewInit
中执行此操作,因为这将导致ExpressionHasChangedAfterChecked
错误.将静态标志设置为true将在ngOnInit中创建视图.
然而:
在大多数其他情况下,最佳做法是使用{static: false}
.
请注意,{ static: false }
选项将在Angular 9中默认设置.这意味着不再需要设置静态标志,除非您想使用static: true
选项.
可以使用angular cli ng update
命令自动升级当前代码库.
有关迁移指南和有关这方面的更多信息,您可以查看here和here
#静态查询和动态查询之间有什么区别?
对于静电查询(静电: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
已经装满了.