引言:每位 Angular 开发者的共同痛点
\n\n您是否曾花费一个小时寻找一个隐藏在一行代码中的错误?如果您正在使用 Angular Material Autocomplete,并遇到了 Can't bind to 'formControl' since it isn't a known property of 'input' 这个错误——您并不孤单。这个问题在 Stack Overflow 上获得了成千上万的浏览量,这并非偶然。这个错误总是在您认为一切运行完美时,在最意想不到的时刻出现。
在本文中,我们将深入分析 错误产生的原因,详细比较三种修复方法,并提供 TypeScript 的工作示例。阅读本文后,您不仅能修复自动补全功能,还能更深入地理解 Angular 的架构。让我们开始吧!
\n\n为什么会出现 Can't bind to 'formControl' 错误?
\n\n让我们直入主题。当 Angular 尝试将 formControl 指令绑定到 <input> 元素,但在当前模块中找不到它时,就会出现此错误。听起来很合理,但细节决定成败。
实际上,formControl 是一个指令的选择器,它是 ReactiveFormsModule 模块的一部分。如果您忘记导入此模块或导入不正确,Angular 就不知道如何处理您输入框上的 [formControl] 属性。
这是一个典型的情况:您创建了一个带有自动补全功能的新组件,在 TypeScript 代码中添加了 FormControl,然后在模板中编写:
<input type="text" [formControl]="myControl" [matAutocomplete]="auto">\n<mat-autocomplete #auto="matAutocomplete">\n <mat-option *ngFor="let option of filteredOptions | async" [value]="option">\n {{option}}\n </mat-option>\n</mat-autocomplete>\n\n然后——砰!控制台中出现红色错误。熟悉吗?那么请继续阅读。
\n\n方法 1:导入 ReactiveFormsModule(最简单且正确的方法)
\n\n第一种也是最明显的方法是确保 ReactiveFormsModule 已导入到正确的模块中。对于独立组件(Angular 14+)或经典模块,步骤略有不同。
\n\n对于经典模块 (NgModule)
\n\n打开注册了您组件的模块文件(例如 app.module.ts 或 shared.module.ts),并添加导入:
import { ReactiveFormsModule } from '@angular/forms';\nimport { MatAutocompleteModule } from '@angular/material/autocomplete';\nimport { MatInputModule } from '@angular/material/input';\n\n@NgModule({\n imports: [\n ReactiveFormsModule,\n MatAutocompleteModule,\n MatInputModule,\n // 其他导入\n ],\n // ...\n})\nexport class AppModule { }\n\n重要提示: 如果没有 MatInputModule,matInput 指令也无法工作,您会遇到类似的错误。请同时导入这三个模块。
对于独立组件 (Angular 14+ 和 Angular 17)
\n\n如果您使用新的架构,导入直接在组件中进行:
\n\nimport { Component } from '@angular/core';\nimport { ReactiveFormsModule, FormControl } from '@angular/forms';\nimport { MatAutocompleteModule } from '@angular/material/autocomplete';\nimport { MatInputModule } from '@angular/material/input';\nimport { AsyncPipe } from '@angular/common';\n\n@Component({\n selector: 'app-search',\n standalone: true,\n imports: [\n ReactiveFormsModule,\n MatAutocompleteModule,\n MatInputModule,\n AsyncPipe\n ],\n template: `\n <input type="text" [formControl]="myControl" [matAutocomplete]="auto">\n <mat-autocomplete #auto="matAutocomplete">\n <mat-option *ngFor="let option of filteredOptions | async" [value]="option">\n {{option}}\n </mat-option>\n </mat-