我正在尝试使用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)
答案 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