@ViewChild(CdkPortalOutlet) 在 AfterViewInit 中返回 undefined

Nit*_*eli 2 javascript angular angular-cdk

尝试查询 a ng-templatewithCdkPortalOutlet总是不成功,我不明白为什么?

<ng-template CdkPortalOutlet></ng-template>

@ViewChild(CdkPortalOutlet) test: CdkPortalOutlet;
Run Code Online (Sandbox Code Playgroud)

闪电战

yur*_*zui 7

为了使用CdkPortalOutlet指令在AppComponent模板中,您有进口PortalModuleAppModule(即NgModule其中AppComponent已申报)

import { PortalModule } from '@angular/cdk/portal';
...

@NgModule({
  imports:      [ BrowserModule, FormsModule, PortalModule, OverlayModule ],
                                              ^^^^^^^^^^^^
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

此外,Angular HTML 解析器区分大小写,因此您需要像这样使用它:

<ng-template cdkPortalOutlet></ng-template>
             ^^^
          lower case
Run Code Online (Sandbox Code Playgroud)

分叉的堆栈闪电战


j3f*_*3ff 5

由于 Angular 8@ViewChild需要提供一个额外的static参数,并且文档很难找到将其设置为什么值。如果设置不正确,undefined尝试CdkPortalOutlet使用@ViewChild.

TLDR

@ViewChild(CdkPortalOutlet, { static: true })迁移到 Angular 8 时设置。

从 Angular 代码中提取的注释

如何选择static要使用的标志值:truefalse

我们一直建议在ngAfterContentInit内容查询中检索查询结果。这是因为当这个生命周期钩子运行时,相关节点的变更检测已经完成,我们可以保证我们已经收集了所有可能的查询结果。

大多数应用程序都希望使用{static: false}这个原因。此设置将确保查询会找到依赖于绑定解析的查询匹配(例如*ngIfs 或*ngFors内的结果)。如果您需要访问TemplateRef查询中的 a 以动态创建视图,则无法在ngAfterContentInit. 更改检测已经在该视图上运行,因此使用模板创建新视图将导致ExpressionHasChangedAfterChecked抛出错误。在这种情况下,您需要将static标志设置为true并在ngOnInit. 在大多数其他情况下,最佳做法是使用{static: false}.

但是,为了便于迁移到版本 8,您可能还需要将static标志设置为true如果您的组件代码已经依赖于某个时间之前 可用的查询结果ngAfterContentInit。例如,如果您的组件依赖于在ngOnInit钩子或@Inputsetter 中填充的查询结果,您将需要将标志设置为true或重新工作您的组件以适应以后的时间。

注意:选择静态选项意味着查询结果嵌套在查询中*ngIf*ngFor不会被查询找到。只有在运行变更检测后才能检索这些结果。