通过ngTemplateOutlet的Angular CDK Stepper Footer模板

时间:2019-05-18 03:43:10

标签: angular angular-material angular-cdk angular-material-stepper

我正在尝试使用Angular CDK Stepper创建通用的stepper组件,如此处https://material.angular.io/guide/creating-a-custom-stepper-using-the-cdk-stepper所述。

我想使用ngTemplateOutlet通过模板引用传递步进器的页眉和页脚模板。

当我在按钮中传递cdkStepperPrevious,cdkStepperNext时,模板不起作用。

可以在这里https://stackblitz.com/edit/angular-bgyqqz-r8axmr

找到代码
<ng-template #stepperHeader>
  <header>
    <h2> Header</h2>
  </header>
</ng-template>
<ng-template #stepperFooter>
    <button class="example-nav-button" cdkStepperPrevious>Next</button>
    <button class="example-nav-button" cdkStepperNext>Previous</button>
</ng-template>
<example-custom-stepper [headerTemplate]="stepperHeader" [footerTemplate]="stepperFooter">

  <cdk-step> <p>This is any content of "Step 1"</p> </cdk-step>
  <cdk-step> <p>This is any content of "Step 2"</p> </cdk-step>
</example-custom-stepper>

and in my example-custom-stepper component

<section class="example-container">
   <ng-container [ngTemplateOutlet]="headerTemplate"></ng-container>
  <div [style.display]="selected ? 'block' : 'none'">
    <ng-container [ngTemplateOutlet]="selected.content"></ng-container>
  </div>

  <footer class="example-step-navigation-bar">
    <ng-container [ngTemplateOutlet]="footerTemplate"></ng-container>
  </footer>
</section>

错误

preview-4adb70f742b91f09679fb.js:1错误错误:StaticInjectorError(AppModule)[CdkStep-> CdkStepper]:   StaticInjectorError(平台:核心)[CdkStep-> CdkStepper]:     NullInjectorError:CdkStepper没有提供程序!     在NullInjector.get(injector.ts:43)     在resolveToken(injector.ts:346)     在tryResolveToken(injector.ts:288)     在StaticInjector.get(injector.ts:168)     在resolveToken(injector.ts:346)     在tryResolveToken(injector.ts:288)     在StaticInjector.get(injector.ts:168)     在resolveNgModuleDep(ng_module.ts:125)     在NgModuleRef_.get(refs.ts:507)     在resolveDep(provider.ts:423)

1 个答案:

答案 0 :(得分:2)

请注意,ng-template,ng-container或ngTemplateOutlet并不是罪魁祸首。

您正在cdk-custom-stepper-without-form-example.html中使用cdkStepperPrevious和cdkStepperNext指令。签出支持html文件的组件。 CdkCustomStepperWithoutFormExample组件中没有CdkStepper的提供程序。仅在提供cdkStepper之后,才能使用cdk指令。解决方法是将以下代码添加到@Component指令中: 提供者:[{提供:CdkStepper}]

但是,那不能解决问题。每当声明ng-template时,模板内的所有指令和事件都将与定义html文件的组件相关联。打开开发人员选项,然后检查ng-container内部显示的按钮。您会看到_ngcontent-xxx-c1模式的html标记。如果您查看其他元素的html标记,它们将显示为_ngcontent-xxx-c0。这意味着ng容器的内容不属于呈现它的组件。 (用_ngcontent-xxx-c#标记组件的每个元素,其中#是组件的数量。)有关更多信息,请参见以下链接:

What does _ngcontent-c# mean in Angular?

这意味着在按钮中指定的cdkStepperPrevious和cdkStepperNext指令将尝试调用CdkCustomStepperWithoutFormExample类中的实现,即使它们在CustomStepper组件中进行了呈现。但是,该类不会扩展CdkStepper。因此,_stepper实例将保持未定义状态。看看CdkStepperNext / Previous指令的源代码。

https://github.com/angular/components/blob/master/src/cdk/stepper/stepper-button.ts

这两个指令的构造函数都采用CdkStepper类型的_stepper实例。这仅在CustomStepper类内部可用。

因此,如果您想让代码正常工作,则应在example-custom-stepper.html文件中任意位置定义包含页脚的ng-template。然后,如果尝试在ng-container中渲染该模板,则它将按预期工作,因为cdkStepperPrevious / Next指令的构造函数所需的_stepper实例在CustomStepper类中可用。

1)从CdkCustomStepperWithoutFormExample组件中删除页脚

2)将其添加到CustomStepper