3

我正在尝试使用 Angular CDK 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(Platform: core)[CdkStep -> CdkStepper]: NullInjectorError: No provider for 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)

4

1 回答 1

3

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

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

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

_ngcontent-c# 在 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

于 2020-02-08T11:40:25.273 回答