在大多数情况下,您会想要使用{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
已经填充。