📅  最后修改于: 2023-12-03 15:10:26.791000             🧑  作者: Mango
当开发 Angular 应用时,我们常常会使用 ngModel 指令来实现数据双向绑定。然而,有时候会出现以下错误信息:
无法绑定到“ngModel”,因为它不是“输入”的已知属性。
这是因为,ngModel 不是一个“输入属性”。那么什么是“输入属性”呢?
在 Angular 中,指令通过“输入属性”与组件进行交互,也可以把它们看作在组件和指令之间传递数据的门户。例如,通过 @Input 装饰器可以将属性绑定到组件:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-my-component',
template: `<h1>Hello {{name}}!</h1>`
})
export class MyComponent {
@Input() name: string;
}
在此示例中,@Input() 装饰器将 name 属性声明为组件的输入属性。这意味着该属性的值可以来自组件的父组件,通过属性绑定语法将其传递给组件:
<app-my-component [name]="'John'"></app-my-component>
然而,ngModel 并非组件的输入属性。相反,它是一个指令,用于实现双向绑定。这就是为什么在某些情况下,Angular 编译器会报告无法将 ngModel 绑定到组件的原因。
要解决此问题,可以在组件的构造函数中导入 ControlValueAccessor:
import { Component, OnInit, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyComponent),
multi: true
}
]
})
export class MyComponent implements OnInit, ControlValueAccessor {
value: any;
constructor() { }
ngOnInit() {
}
writeValue(value: any) {
this.value = value;
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
onChange(value: any) {}
onTouched() {}
}
在此示例中,我们将实现 ControlValueAccessor 接口的 MyComponent 声明为组件提供程序的一个提供。该接口有四个方法:
要将组件与 ngModel 一起使用,可以使用 [(ngModel)] 语法:
<app-my-component [(ngModel)]="myValue"></app-my-component>
请注意,如果要使用 [(ngModel)],则必须同时导入 FormsModule 和 ReactiveFormsModule 模块。
以上是解决“无法绑定到‘ngModel’,因为它不是‘输入’的已知属性”的方法。在某些情况下,将 ControlValueAccessor 接口实现为组件的提供程序可用于解决此问题。请记住,ngModel 并非组件的输入属性,因此无法像其他组件输入属性那样进行绑定。