Angular 17升级后'mat-form-field'未知元素错误求助
Angular 12升级到17后Material组件'mat-form-field'未知元素错误
核心错误信息
src/app/pages/table-maintenance/maintain-invalid-tax-id/modal/maintain-invalid-tax-id-modal.component.html:5:7 - error NG8001: 'mat-form-field' is not a known element:
- 若'mat-form-field'是Angular组件,请确认它属于当前模块。
- 若'mat-form-field'是Web组件,请将'CUSTOM_ELEMENTS_SCHEMA'添加到该组件的'@NgModule.schemas'中以抑制此消息。
相关代码
maintain-invalid-tax-id-modal.component.html
<h2 mat-dialog-title>ADR Foreign Tax Reclaims: {{description}} TaxIds</h2> <div mat-dialog-content> <form [formGroup]="invalidTaxIdsForm"> <div fxLayout fxLayoutGap="20px"> <mat-form-field> <mat-label class="bold">Invalid Tax ID</mat-label> <input matInput type="text" placeholder="Invalid Tax ID" maxlength="10" cdkFocusInitial formControlName="invalidTaxId" /> <mat-error *ngIf="invalidTaxIdsForm.controls.invalidTaxId.touched && invalidTaxIdsForm.controls.invalidTaxId?.errors"> Tax id must be entered. </mat-error> </mat-form-field> </div> <div fxLayout fxLayoutGap="20px"> <mat-form-field> <mat-label class="bold">Comment</mat-label> <input matInput type="text" maxlength="255" placeholder="Comment" formControlName="comment" /> </mat-form-field> </div> <div> <mat-label class="bold mat-red">{{errorMsg}}</mat-label> </div> <div fxLayout="row" fxLayoutGap="20px"> <button fxFlex="25" mat-raised-button color="primary" *ngIf="isAdd (click)="addNew()">Submit</button> <button fxFlex="25" mat-raised-button color="primary" *ngIf="isEdit" (click)="updateInvalidTaxIds()">Submit</button> <button fxFlex="25" mat-raised-button color="secondary" (click)="close()">Cancel</button> </div> </form> </div>
maintain-invalid-tax-id-modal.component.ts
import { Component, Inject, OnInit, Optional } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { AppConstants } from '@app/shared/models/app-constants'; import { MaintainInvalidTaxIdsModel } from '../models/maintain-invalid-taxId.model'; import { MaintainInvalidTaxIdService } from '../services/maintain-invalid-tax-id.service'; @Component({ selector: 'app-maintain-invalid-tax-id-modal', templateUrl: './maintain-invalid-tax-id-modal.component.html', styleUrls: ['./maintain-invalid-tax-id-modal.component.scss'] }) export class MaintainInvalidTaxIdModalComponent implements OnInit { invalidTaxIdsForm: UntypedFormGroup; description: string; action: string; errorMsg: string; isEdit: boolean = false; isAdd: boolean = false; constructor(private formBuilder: UntypedFormBuilder, public dialog: MatDialog, private service:MaintainInvalidTaxIdService , public dialogRef: MatDialogRef<MaintainInvalidTaxIdModalComponent>, @Optional() @Inject(MAT_DIALOG_DATA) public data: MaintainInvalidTaxIdsModel) { } ngOnInit(): void { this.actionInitializer(); this.createForm(); if (this.isEdit) { this.patchEditForm(); this.invalidTaxIdsForm.controls['invalidTaxId'].disable(); } } //[Code removed for brevity] }
app.module.ts
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { APP_INITIALIZER, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { LoginComponent } from './pages/login/login.component'; import { LogoutComponent } from './pages/logout/logout.component'; import { appInitializer } from './app.initializer'; import { environment } from '@environments/environment'; //Modules import { AppRoutingModule } from './app-routing.module'; import { MaterialModule } from './material-module'; import { ControlsModule } from 'src/app/controls/controls.module'; import { SharedComponentsModule } from './shared/components/shared-components.module'; import { NgIdleModule } from '@ng-idle/core'; import { MatFormFieldModule } from '@angular/material/form-field' import { MatInputModule } from '@angular/material/input'; //Interceptors import { JwtInterceptor } from 'src/app/shared/interceptors/jwt/jwt.interceptor'; import { LoadingSpinnerInterceptor } from './shared/interceptors/loading-spinner/loading-spinner.interceptor'; import { ServiceUnavailableInterceptor } from './shared/interceptors/status-code/service-unavailable.interceptor'; import { Status401Interceptor } from 'src/app/shared/interceptors/status-code/status-401.interceptor'; import { Status404Interceptor } from 'src/app/shared/interceptors/status-code/status-404.interceptor'; import { Status405Interceptor } from './shared/interceptors/status-code/status-405.interceptor'; import { Status500Interceptor } from './shared/interceptors/status-code/status-500.interceptor'; //Layout import { HeaderComponent } from 'src/app/shared/layout/header/header.component'; import { FooterComponent } from 'src/app/shared/layout/footer/footer.component'; import { NavMenuComponent } from 'src/app/shared/layout/nav-menu/nav-menu.component'; //Services import { ConfigurationService } from './shared/services/configuration/configuration.service'; import { ENVIRONMENT } from './shared/services/configuration/environment-token'; import { AuthenticationService } from "@app/shared/services/authentication/authentication.service"; import { LoggingService } from '@app/shared/services/logging/logging.service'; import { LogPublisherService } from '@app/shared/services/logging/log-publisher.service'; export function initConfiguration(configService: ConfigurationService) { return () => configService.loadApiConfig(); } @NgModule({ declarations: [ AppComponent, HeaderComponent, FooterComponent, NavMenuComponent, LoginComponent, LogoutComponent ], imports: [ AppRoutingModule, BrowserModule, BrowserAnimationsModule, HttpClientModule, FormsModule, ReactiveFormsModule, MaterialModule, ControlsModule, SharedComponentsModule, NgIdleModule.forRoot(), MatFormFieldModule, MatInputModule ], providers: [ { provide: ENVIRONMENT, useValue: environment }, { provide: APP_INITIALIZER, useFactory: initConfiguration, multi: true, deps: [ConfigurationService] }, LoadingSpinnerInterceptor, LoggingService, LogPublisherService, { provide: APP_INITIALIZER, useFactory: appInitializer, multi: true, deps: [AuthenticationService] }, { provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: LoadingSpinnerInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: Status500Interceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: Status404Interceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: Status405Interceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: Status401Interceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ServiceUnavailableInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
解决方案
1. 在组件所属子模块中导入Material模块
MaintainInvalidTaxIdModalComponent 不在根模块 AppModule 的 declarations 中,说明它属于某个子模块(如 TableMaintenanceModule)。需要在该子模块的 imports 数组中添加 MatFormFieldModule 和 MatInputModule,而不是仅在根模块导入。Angular模块作用域隔离,根模块导入的模块不会自动传递给子模块。
2. 适配Angular 17独立组件模式
如果项目启用了独立组件,需在组件的 @Component 装饰器中直接导入所需Material模块:
@Component({ selector: 'app-maintain-invalid-tax-id-modal', templateUrl: './maintain-invalid-tax-id-modal.component.html', styleUrls: ['./maintain-invalid-tax-id-modal.component.scss'], standalone: true, imports: [MatFormFieldModule, MatInputModule, ReactiveFormsModule, MatDialogModule, MatButtonModule] })
3. 检查自定义MaterialModule的导出配置
若子模块导入了自定义的 MaterialModule,需确保该模块导出了 MatFormFieldModule 和 MatInputModule:
// material-module.ts import { NgModule } from '@angular/core'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; @NgModule({ imports: [MatFormFieldModule, MatInputModule], exports: [MatFormFieldModule, MatInputModule] // 必须导出才能让子模块使用 }) export class MaterialModule { }
4. 清理缓存并重新构建
- 清除Angular缓存:
ng cache clean - 删除依赖文件:
rm -rf node_modules package-lock.json(Windows:rmdir /s /q node_modules && del package-lock.json) - 重新安装依赖:
npm install - 重新构建项目:
ng build
内容的提问来源于stack exchange,提问作者Scott Michael
相关产品推荐
相关产品推荐

