How should I use the new static option for @ViewChild in Angular 8?
我应该如何配置新的Angular 8视图子级?
1 2 | @ViewChild('searchText', {read: ElementRef, static: false}) public searchTextInput: ElementRef; |
与
1 2 | @ViewChild('searchText', {read: ElementRef, static: true}) public searchTextInput: ElementRef; |
哪个更好? 我什么时候应该使用
在大多数情况下,您将要使用
何时使用
1 2 3 4 5 6 7 8 9 10 11 12 | @Component({ template: ` Am I here? <button (click)="showMe = !showMe"></button> ` }) export class ExampleComponent { @ViewChild('viewMe', { static: false }) viewMe?: ElementRef<HTMLElement>; showMe = false; } |
引入了
不过:
In most other cases, the best practice is to use
{static: false} .
请注意,尽管
您可以使用angular cli
有关迁移指南以及更多有关此的信息,可以在此处和此处查看
What is the difference between static and dynamic queries?
The static option for @ViewChild() and @ContentChild() queries determines when the query results become available.
With static queries (static: true), the query resolves once the view has been created, but before change detection runs. The result, though, will never be updated to reflect changes to your view, such as changes to ngIf and ngFor blocks.
With dynamic queries (static: false), the query resolves after either ngAfterViewInit() or ngAfterContentInit() for @ViewChild() and @ContentChild() respectively. The result will be updated for changes to your view, such as changes to ngIf and ngFor blocks.
因此,根据经验,您可以执行以下操作:
-
当您要访问
ngOnInit 中的ViewChild 时,需要设置{ static: true } 。 -
{ static: false } 只能在ngAfterViewInit 中访问。当模板中的元素上具有结构化指令(即*ngIf )时,这也是您要追求的目标。
从角度文档
static - whether or not to resolve query results before change detection runs (i.e. return static results only). If this option is not provided, the compiler will fall back to its default behavior, which is to use query results to determine the timing of query resolution. If any query results are inside a nested view (e.g. *ngIf), the query will be resolved after change detection runs. Otherwise, it will be resolved before change detection runs.
如果孩子不依赖任何条件,最好使用
PS:由于它是一项新功能,我们可能需要运行性能基准。
编辑
如@Massimiliano Sartoretto所述,github commit可能会为您提供更多见解。
来到这里是因为在升级到Angular 8后,ngOnInit中的ViewChild为null。
静态查询在ngOnInit之前填充,而动态查询(静态:false)在之后填充。换句话说,如果在设置static:false后ngOnInit中的viewchild现在为null,则应考虑更改为static:true或将代码移至ngAfterViewInit。
参见https://github.com/angular/angular/blob/master/packages/core/src/view/view.ts#L332-L336
其他答案是正确的,并解释了为什么会这样:查询依赖于结构指令,例如ngIf内的ViewChild引用应在解析此伪指令的条件之后(即更改检测之后)运行。但是,可以安全地使用static:true,从而在ngOnInit之前解析查询以获取未嵌套的引用。恕我直言,这种特殊情况值得一提,因为空异常可能是您遇到这种特殊性的第一种方式,对我而言。
查看子@angular 5+令牌两个参数("本地引用名称",静态:false | true)
1 | @ViewChild('nameInput', { static: false }) nameInputRef: ElementRef; |
知道真假之间的区别检查此
static - whether or not to resolve query results before change detection runs (i.e. return static results only). If this option is not provided, the compiler will fall back to its default behavior, which is to use query results to determine the timing of query resolution. If any query results are inside a nested view (e.g. *ngIf), the query will be resolved after change detection runs. Otherwise, it will be resolved before change detection runs.
在ng8中,您可以手动设置何时访问父组件中的子组件。
将static设置为true时,这意味着父组件仅在
例如:
1 2 3 4 5 6 7 8 | // You got a childComponent which has a ngIf/for tag ngOnInit(){ console.log(this.childComponent); } ngAfterViewInit(){ console.log(this.childComponent); } |
如果static为false,则仅在ngAfterViewInit()中得到定义,在ngOnInit()中得到未定义。