我应该如何配置新的角度8视图子?
@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;
VS
@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;
哪一个好些?什么时候应该使用静态:true
和静态:false
?
在大多数情况下,您将希望使用{static:false}
。这样设置它将确保找到依赖于绑定解析的查询匹配(如结构指令*NGIF等..
)。
何时使用statice: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标志,除非您希望使用statice:true
选项。
您可以使用angular cling update
命令自动升级当前的代码库。
有关迁移指南和更多信息,您可以查看这里和这里
#静态查询和动态查询有什么区别?@viewChild()和@contentChild()查询的静态选项确定查询结果何时可用。
对于静态查询(static:true),查询在视图创建后解析,但在更改检测运行之前解析。但是,结果永远不会更新以反映对视图的更改,例如对ngIf和ngFor块的更改。
对于动态查询(静态:false),查询分别在@ViewChild()和@ContentChild()的ngAfterViewInit()或ngAfterContentInit()之后解析。对于您的视图的更改,如对ngIf和ngFor块的更改,将更新结果。
使用statice:true
的一个好用例是使用fromevent
绑定到模板中定义的元素。请考虑以下模板:
<div [ngStyle]="thumbStyle$ | async" #thumb></div>
然后,您可以处理该元素上的事件,而不需要使用订阅或init挂钩(如果您不想或不能使用角度事件绑定):
@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
管道订阅它时。因为我们使用的是statice:true
,所以已经填充了this.thumb
。