gpt4 book ai didi

Angular Material Stepper - 如何动态创建组件以加载到步骤中

转载 作者:行者123 更新时间:2023-12-03 17:02:35 27 4
gpt4 key购买 nike

我看过很多类似的帖子,但没有一个能帮助我。

我希望能够使用 @ngFor创建组件然后加载到 Material Stepper 的步骤中

我一直在关注 example of dynamic loading ,以及其他一些帖子(不完整),并提出以下内容。

首先,我有许多要加载到步骤中的组件。除了字符串之外,它们只是空的(例如“组件正在工作”

例如

export class StepPage1Component implements OnInit, StepPage {
constructor() { }
ngOnInit() {
}
}

所以我有3个。

“根”组件如下。
export class WizardStepperComponent implements OnInit {
@ViewChild('stepper') private myStepper: MatStepper;
totalStepsCount: number;

public steps: StepPage[];

constructor(private stepsService: StepPagesService) {
this.steps = [
new StepPage1Component,
new StepPage2Component,
new StepPage3Component
]
}

标记:
<mat-horizontal-stepper #stepper>
<mat-step *ngFor='let step of steps'>
<app-step-page-wrapper item='step'></app-step-page-wrapper>
</mat-step>
</mat-horizontal-stepper>

<!-- second option -->
<div>
<button (click)="goBack(stepper)" type="button" [disabled]="stepper.selectedIndex === 0">Back</button>
<button (click)="goForward(stepper)" type="button"
[disabled]="stepper.selectedIndex === stepper._steps.length-1">Next</button>

<!-- using totalStepsCount -->
<!-- <button (click)="goForward(stepper)" type="button" [disabled]="stepper.selectedIndex === totalStepsCount-1">Next</button> -->
</div>

所以在上面的标记中,我有 ngFor我有问题。

包装器如下...
import { Component, OnInit, Input, ViewChild, ComponentFactoryResolver } from '@angular/core';
import { directiveDef } from '@angular/core/src/view';
import { PageDirective } from '../page.directive';

@Component({
selector: 'app-step-page-wrapper',
template: '<ng-template pageDirective></ng-template>',
})
export class StepPageWrapperComponent implements OnInit {
@Input() item?: any;
@ViewChild(PageDirective) pageHost: PageDirective;

constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

ngOnInit() {
if (this.item == undefined) {
console.error('Item undefined');
return
}

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.item);
const viewContainerRef = this.pageHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
}
}

最后它使用的指令是..
import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
selector: '[pageDirective]'
})
export class PageDirective {

constructor(public viewContainerRef: ViewContainerRef) { }
}

所以,我正在尝试使用 StepPageWrapperComponent将每个组件作为输入( item ),然后使用 componentFactoryResolver创建组件,然后将其“附加”到模板中的指令,即 pageDirective<ng-template pageDirective></ng-template>
但是,当我运行它时,出现以下错误..
        ERROR Error: No component factory found for step. Did you add it to @NgModule.entryComponents?
at noComponentFactoryError (core.js:9877)
at CodegenComponentFactoryResolver.push../node_modules/@angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (core.js:9915)
at StepPageWrapperComponent.push../src/app/step-page-wrapper/step-page-wrapper.component.ts.StepPageWrapperComponent.ngOnInit (step-page-wrapper.component.ts:21)
at checkAndUpdateDirectiveInline (core.js:22099)
at checkAndUpdateNodeInline (core.js:23363)
at checkAndUpdateNode (core.js:23325)
at debugCheckAndUpdateNode (core.js:23959)
at debugCheckDirectivesFn (core.js:23919)
at Object.eval [as updateDirectives] (WizardStepperComponent.html:3)
at Object.debugUpdateDirectives [as updateDirectives] (core.js:23911)

如果我在 StepPageWrapperComponent 中放置一个断点, this.item只是似乎是一个字符串!

enter image description here

所以,这个字符串“step”应该是 ngFor 变量......

enter image description here

但它只是以字符串的形式出现,而不是组件。

有没有人对我在这里做错了什么有任何想法,或者即使有更好的方法来做到这一点?

有关更多详细信息,可以从 https://github.com/pjc2007/wizard-stepper1.git 克隆此样本的来源。

在此先感谢您的帮助!

[19 年 8 月 30 日更新]

输入不起作用的原因是我在将变量传递给输入时忘记了方括号..即我有
<app-step-page-wrapper item='step'></app-step-page-wrapper>

代替
    <app-step-page-wrapper [item]='step'></app-step-page-wrapper>

我现在有组件作为 StepPageWrapperComponent 的输入正如预期的那样。

enter image description here

所以,我现在的问题是执行行 const componentFactory=this.componentFactoryResolver.resolveComponentFactory(this.item) 时抛出的以下错误
ngComponent: StepPage1Component {}
message: "No component factory found for [object Object]. Did you add it to @NgModule.entryComponents?"
stack: "Error: No component factory found for [object Object]. Did you add it to @NgModule.entryComponents?↵ at noComponentFactoryError (http://localhost:4200/vendor.js:71338:17)↵ at CodegenComponentFactoryResolver.push../node_modules/@angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (http://localhost:4200/vendor.js:71376:19)↵ at StepPageWrapperComponent.push../src/app/step-page-wrapper/step-page-wrapper.component.ts.StepPageWrapperComponent.ngOnInit (http://localhost:4200/main.js:244:66)↵ at checkAndUpdateDirectiveInline (http://localhost:4200/vendor.js:83560:19)↵ at checkAndUpdateNodeInline (http://localhost:4200/vendor.js:84824:20)↵ at checkAndUpdateNode (http://localhost:4200/vendor.js:84786:16)↵ at debugCheckAndUpdateNode (http://localhost:4200/vendor.js:85420:38)↵ at debugCheckDirectivesFn (http://localhost:4200/vendor.js:85380:13)↵ at Object.eval [as updateDirectives] (ng:///AppModule/WizardStepperComponent.ngfactory.js:16:5)↵ at Object.debugUpdateDirectives [as updateDirectives] (http://localhost:4200/vendor.js:85372:21)"
__proto__: Object

将此作为 entryComponent

IE
@NgModule({
declarations: [
AppComponent,
WizardStepperComponent,
StepPage1Component,
StepPage2Component,
StepPage3Component,
PageDirective,
StepPageWrapperComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatStepperModule,
MatInputModule,
MatButtonModule,
MatAutocompleteModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [
StepPage1Component,
StepPage2Component,
StepPage3Component,
StepPageWrapperComponent
]

[更新 2 19 年 8 月 30 日]

走进 this.componentFactoryResolver.resolveComponentFactory ,我看到以下...

enter image description here

所以组件似乎在 map 中,但 map.get 返回未定义?

最佳答案

So the component seems to be in the map, but the map.get is returning undefined?



是的,这是误导。您传递的是类的实例而不是类本身。

考虑以下示例:
class Test {}
console.log(Test); // class Test {}
console.log(new Test()); // Test {}

如您所见,输出非常相似,但它们是两种不同的东西。

所以解决办法是通过 组件类型 而不是组件实例:
this.steps = [
StepPage1Component,
StepPage2Component,
StepPage3Component
]

关于Angular Material Stepper - 如何动态创建组件以加载到步骤中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57705694/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com