无路由的 Angular 延迟加载组件 - 表单控件名称没有值访问器

问题描述 投票:0回答:1

我正在尝试在没有路由的情况下延迟加载组件。 我有两个组件,每个 formGroup 一个组件。

formGroup
位于名为
vehicleForm
的父组件处,包括名为
FormControl
vehicleDetail

子组件中的

formGroup
,包括
fuel
model

现在在

vehicle.component.html
我在
formControlName='vehicleDetail'
(加载子组件的位置)上添加
<ng-template>
来获取子表单的嵌套值,我遇到了这个问题:

No value accessor for form control name: 'vehicleDetail'

No value accessor for form control name: 'fuel'

No value accessor for form control name: 'model'

这是我的代码:

// vehicle.component.ts (This is Parent component)

export class VehicleComponent implements OnInit {
  public vehicleForm: FormGroup = new FormGroup({
    vehicleDetail: new FormControl('')
  });
  
  @ViewChild("vehicleDetailLazyLoadComponent", {read: ViewContainerRef}) vehicleDetailLazyLoadComponent!: ViewContainerRef;
  
  constructor(private injector: Injector){}
  
  ngOnInit(){}
  
  openVehicleDetail() {
    this.loadVehicleDetailComp();
  }
  
  async loadVehicleDetailComp(){
    const {VehicleDetailModule, VehicleDetailComponent} = await import("./vehicle-detail.component.ts");
    const moduleRef = createNgModule(VehicleDetailModule, this.injector)
    this.vehicleDetailLazyLoadComponent.clear();
    const {instance} = this.vehicleDetailLazyLoadComponent.createComponent(VehicleDetailComponent, {ngModuleRef: moduleRef});
  }
}
//vehicle.component.html (This is Parent Component)

<form [formGroup]="vehicleForm">
  <button (click)="openVehicleDetail()">Click</button>
  
  <ng-template #vehicleDetailLazyLoadComponent formControlName="vehicleDetail"></ng-template>
</form>

// vehicleDetail.component.ts (This is Child component)
@Component({
  selector: 'app-vehicle-detail',
  templateUrl: './vehicle-detail.component.html',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => VehicleDetailComponent),
      multi: true
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => VehicleDetailComponent),
      multi: true
    }
  ]
})

export class VehicleDetailComponent implements OnInit {
  form: formGroup;
  
  constructor(private fb: FormBuilder){
  }
  
  ngOnInit(){
    this.form = this.fb.group({
      model: new FormControl('', Validators.required),
      fuel: new FormControl('')
    })
  }
}

@NgModule({
  declarations: [VehicleDetailComponent],
  imports: [
    CommonModule,
    ReactiveFormsModule,
    NgbModule,
    FormsModule,
    NgSelectModule
  ],
  providers: [
  ],
  bootstrap: [VehicleDetailComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

export class VehicleDetailModule {
  constructor() {}
}
// vehicleDetail.component.html (This is Child component)
<form [formGroup]="form">
  Model: <input formControlName="model" />
  Fuel: <input formControlName="fuel" />
</form>

这个问题是否是因为在 DOM 树中渲染时无法在

formControlName="vehicleDetail"
上添加
<app-vehicle-detail></app-vehicle-detail>
导致的? 有人知道我该如何解决这个问题吗?谢谢!

javascript angular angularjs lazy-loading angular-components
1个回答
0
投票

这里有几个问题。第一个与您在控制台上看到的错误直接相关的是:在vehicleDetail.component.ts 中,您创建 FormGroup 太晚了。当执行 ngOnInit 时,模板已经渲染完毕。所以 Angular 已经尝试为“模型”找到一个 formControl - 但它尚未创建。您可以通过将表单初始化放入构造函数中或通过在表单元素的模板中添加 *ngIf="form" 来解决该问题。

我在这里看到的其他问题:

  • 此处不需要 NG_VALUE_ACCESSOR。仅当您想构建自己的表单控件(例如您自己的自动完成)时才需要它,它直接使用 formControlName 作为从外部给出的参数。
  • 您尝试将子组件插入父表单的方式不起作用。相反,您可以仅使用子组件作为元素(通过使用例如 )。您可以在父组件内部定义整个 formGroup 结构,并可以使用输入绑定将其详细信息部分插入到子组件中。
  • Angular 中的延迟加载是基于路由的。我担心不可能像您一样使用动态导入。此外,对于延迟加载组件,您需要使用独立组件。

还有一些其他的东西,但在这里一一列举就太多了。您是否使用过 cli 来创建此代码?我这样问是因为即使文件名也符合命名约定。

也许您应该首先以更简单的方式进行设置 - 例如没有延迟加载。一旦它起作用,你就可以添加女士加载。

© www.soinside.com 2019 - 2024. All rights reserved.