【问题标题】:Angular Reactive Form Group Issues with Lazy Loaded Components延迟加载组件的 Angular 反应式表单组问题
【发布时间】:2020-09-09 06:36:48
【问题描述】:

我正在尝试在其中一个延迟加载的组件中实现反应式表单,但出现以下错误。

Stackblitz Link

ERROR Error: Uncaught (in promise): Error: Template parse errors:
Can't bind to 'formGroup' since it isn't a known property of 'form'. ("<h3>Product List</h3>

<form [ERROR ->][formGroup]="myForm">

    <input type="text" formControlName="name"/>
"): ng:///ProductsRoutingModule/ProductListComponent.html@2:6
Error: Template parse errors:
Can't bind to 'formGroup' since it isn't a known property of 'form'. ("<h3>Product List</h3>

<form [ERROR ->][formGroup]="myForm">

    <input type="text" formControlName="name"/>
")

package.json

{
  "name": "angular6-lazy-loading",
  "version": "0.0.0",
  "private": true,
  "dependencies": {
    "rxjs": "6.1.0",
    "core-js": "2.5.5",
    "zone.js": "0.8.26",
    "@angular/core": "6.0.0",
    "@angular/forms": "6.0.0",
    "@angular/common": "6.0.0",
    "@angular/router": "6.0.0",
    "@angular/compiler": "6.0.0",
    "@angular/platform-browser": "6.0.0",
    "@angular/platform-browser-dynamic": "6.0.0"
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.901.1",
    "@angular/cli": "~9.1.1",
    "@angular/compiler-cli": "~9.1.1",
    "@angular/language-service": "~9.1.1",
    "@types/node": "^12.11.1",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.4.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~3.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "protractor": "~5.4.3",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.8.3"
  }
}

products.module.ts

import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { ProductsRoutingModule } from "./products-routing.module"; //Added
import { ReactiveFormsModule, FormsModule } from "@angular/forms";

@NgModule({
  imports: [
    CommonModule,
    ProductsRoutingModule,
    ReactiveFormsModule,
    FormsModule
  ],
  declarations: []
})
export class ProductsModule {}

product-list.component.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';

import { AppComponent } from './app.component';
import { ReactiveFormsModule } from "@angular/forms";


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

product-list.component.html

<h3>Product List</h3>

<form [formGroup]="myForm">
    <input type="text" formControlName="name"/>
</form>

我已经在延迟加载模块和应用模块中导入了所需的模块

{ ReactiveFormsModule, FormsModule } from "@angular/forms";

对此有任何想法吗?是bug吗?

https://stackblitz.com/edit/angular6-lazy-loading-gej1nn

【问题讨论】:

    标签: angular lazy-loading angular-routing angular-reactive-forms


    【解决方案1】:

    路由模块应该导出RouterModule

    @NgModule({
      imports: [
        RouterModule.forChild(productRoutes)
      ],
      exports: [RouterModule]
    })
    export class ProductsRoutingModule { }
    

    然后 ProductsModule 可以导入 ProductsRou​​tingModule 如下

    @NgModule({
      imports: [
        CommonModule,
        ProductsRoutingModule,
        ReactiveFormsModule,
        FormsModule
      ],
      declarations: [ProductsComponent, ProductListComponent, ProductDetailComponent ]
    })
    export class ProductsModule {}
    

    declarations 应该在您将用于延迟加载的模块中提供,在本例中为 ProductsModule

    example

    更新

    1. 在 ProductsRou​​tingModule 中,您可以提供路由器设置,但不需要导出 RouterModule,它只是为ProductsModule 提供RouterModule 的一种方式。或者,您可以在 ProductsModule 的导入中提供 RouterModule。为了能够使用路由器模块声明,需要以一种方式提供RouterModule
    2. 如果您在ProductsRoutingModule 定义声明,您还应该通过import 提供同一模块中的所有依赖项,但要使declarations 包含在ProductsModule 中,您还应该通过exports 导出它们

    因此,您也可以像下面一样更改这两个模块,您甚至可以在主模块中有 RouterModule 时省略它

    @NgModule({
      imports: [
        CommonModule,
        ReactiveFormsModule,
        RouterModule.forChild(productRoutes)
      ],
      declarations: [
        ProductsComponent, ProductListComponent, ProductDetailComponent
      ],
      exports: [    
        ProductsComponent, ProductListComponent, ProductDetailComponent
      ]
    })
    export class ProductsRoutingModule { }
    
    @NgModule({
      imports: [
        ProductsRoutingModule
      ]
    })
    export class ProductsModule {}
    

    阅读modules-in-angularasynchronous-modules 可能会很有趣

    【讨论】:

    • 所以唯一的变化是 ProductsRou​​tingModule 中的“路由模块应该导出 RouterModule”?
    • @MithunS no without declarations in ProductsModule 它也不会工作
    • 您能解释一下这背后的原因吗?
    • @MithunS 我添加了一些细节
    【解决方案2】:

    在产品模块而不是路由模块中移动组件声明

    declarations: [ProductsComponent, ProductListComponent, ProductDetailComponent ]
    

    【讨论】:

    • 您能解释一下这背后的原因吗?
    • 当您使用loadChildren: 'app/products/products.module#ProductsModule' 加载产品模块时,组件应声明为该模块。
    【解决方案3】:

    我在 stackblitz 代码中发现了两个错误

    1. 功能模块中的组件应在父模块引用的模块中声明。在你的情况下app.modulelazyloads products.module。但是 products 模块的组件声明在products-routing.module

    2. 路由器模块应该导出RouterModule

    3. products.component 中,模板字符串是在模板文字(backtik)中提供的,将其替换为普通字符串template: '&lt;router-outlet&gt;&lt;/router-outlet&gt;'(引号)

    找到固定代码here

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 2023-03-13
      • 2020-10-17
      相关资源
      最近更新 更多