没有用于表单控件的值访问器
No value accessor for form control
我正在使用 Angular2-rc5,目前我的登录页面出现错误。我正在尝试制作一个表单,但控制台抛出异常告诉我它找不到我的 formcontroll
s,即使我在 init 上创建它也是如此。知道为什么我会收到此错误吗?
登录组件
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { LoginService } from './login.service';
import { User } from '../../models/user';
@Component({
selector: 'login',
providers: [LoginService],
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
private loginForm: FormGroup; // our model driven form
private submitted: boolean; // keep track on whether form is submitted
private events: any[] = []; // use later to display form changes
constructor(private fb: FormBuilder, private ls:LoginService){}
ngOnInit(){
this.loginForm = new FormGroup({
email: new FormControl('',[<any>Validators.required]),
password: new FormControl('', [<any>Validators.required, <any>Validators.minLength(6)]),
rememberMe: new FormControl()
});
}
save(model: User, isValid: boolean) {
console.log("Test");
console.log(model, isValid);
}
// Login in user
login(email: any, password: any){
this.ls.login(email, password, false);
}
}
Page.html
<div id="login-page">
<div class="form-wrapper">
<form class="login-form" [formGroup]="loginForm" novalidate (ngSubmit)="save(loginForm.value, loginForm.valid)">
<div >
<div class="input-field col s12 center">
<p class="center login-form-text">Login page</p>
</div>
</div>
<div >
<div class="input-field col s12">
<input id="email" type="email">
<label class="center-align" for="email" formControlName="email">Email</label>
</div>
</div>
<div >
<div class="input-field col s12">
<input id="password" type="password">
<label class="center" for="password" formControlName="password">Password</label>
</div>
</div>
<div >
<div class="input-field col s12 m12 l12 login-text">
<input id="remember-me" type="checkbox" formControlName="rememberMe">
<label for="remember-me">Remember me</label>
</div>
</div>
<div >
<div class="input-field col s12">
<ahref="index.html">Login</a>
</div>
</div>
<div >
<div >
<p><a href="page-register.html">Register Now!</a></p>
</div>
<div >
<p><a href="page-forgot-password.html">Forgot password ?</a></p>
</div>
</div>
</form>
</div>
</div>
异常
EXCEPTION: Uncaught (in promise): Error: Error in ./LoginComponent
class LoginComponent - inline template:13:45 caused by: No value
accessor for form control with name: 'email'.....
您正在将 formControlName
添加到标签而不是输入。
你有这个:
<div >
<div class="input-field col s12">
<input id="email" type="email">
<label class="center-align" for="email" formControlName="email">Email</label>
</div>
</div>
试试这个:
<div >
<div class="input-field col s12">
<input id="email" type="email" formControlName="email">
<label class="center-align" for="email">Email</label>
</div>
</div>
同时更新其他输入字段。
在我的例子中,我使用了 Angular 表单和 contenteditable
元素,例如 div
并且之前遇到过类似的问题。
我编写了 ng-contenteditable 模块来解决这个问题。
对于带有 angular material 的 UnitTest angular 2,您必须在导入部分添加 MatSelectModule 模块。
import { MatSelectModule } from '@angular/material';
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CreateUserComponent ],
imports : [ReactiveFormsModule,
MatSelectModule,
MatAutocompleteModule,......
],
providers: [.........]
})
.compileComponents();
}));
如果您遇到此问题,那么
- formControlName 不在值访问器元素上。
- 或者您没有导入该元素的模块。
如果必须使用标签为formControl
。就像 Ant Design 的复选框一样。它可能会在 运行 测试时抛出此错误。您可以使用 ngDefaultControl
<label nz-checkbox formControlName="isEnabled" ngDefaultControl>
Hello
</label>
<nz-switch nzSize="small" formControlName="mandatory" ngDefaultControl></nz-switch>
您可以在标签中看到 formControlName ,删除它解决了我的问题
对于在 angular 9+
中遇到此问题的任何人
如果您不声明您的组件或导入声明该组件的模块,也会遇到此问题。
让我们考虑一种情况,您打算使用 ng-select
但您忘记导入它 Angular 将抛出错误 'No value accessor...'
我在 Below stackblitz demo 中重现了这个错误。
在我的例子中,我使用的是 ionic,我试图用 jasmine karma 对 ion-input 进行单元测试。
运行 测试时,我在 karma 浏览器中收到无值访问器错误。所以我只是将 ngDefaultControl
添加到离子输入,它解决了问题。
<ion-input class="password" [(ngModel)]="user.password" name="password"
type="password" #pw="ngModel" required ngDefaultControl>
</ion-input>
对我来说,只有 ionic 日期选择器出现错误,我不得不将 IonicModule
导入我的延迟加载模块
constructor(
private cdr: ChangeDetectorRef,
@Optional()
@Self() public ngControl: NgControl,
) {
if (ngControl) {
ngControl.valueAccessor = this;
}
}
在我的例子中,将这一行添加到自定义控件(可重用)组件的构造函数中
if (ngControl) {
ngControl.valueAccessor = this;
}
对我来说,我在 angular 应用程序中使用 primeng 下拉菜单。
下拉模块未导入。
或
您需要将 formControlName="controlName"
移动到 <mat-radio-group>
包装器,而不是将其绑定到单个 <mat-radio-button>
元素
在某些情况下,您可能会错过将 NG_VALUE_ACCESSOR
添加到可重用组件中作为提供程序。
@Component({
selector: 'app-reusable',
templateUrl: './reusable.component.html',
styleUrls: ['./reusable.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ReusableComponent),
multi: true,
},
],
})
我正在使用 Angular2-rc5,目前我的登录页面出现错误。我正在尝试制作一个表单,但控制台抛出异常告诉我它找不到我的 formcontroll
s,即使我在 init 上创建它也是如此。知道为什么我会收到此错误吗?
登录组件
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators } from '@angular/forms';
import { LoginService } from './login.service';
import { User } from '../../models/user';
@Component({
selector: 'login',
providers: [LoginService],
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
private loginForm: FormGroup; // our model driven form
private submitted: boolean; // keep track on whether form is submitted
private events: any[] = []; // use later to display form changes
constructor(private fb: FormBuilder, private ls:LoginService){}
ngOnInit(){
this.loginForm = new FormGroup({
email: new FormControl('',[<any>Validators.required]),
password: new FormControl('', [<any>Validators.required, <any>Validators.minLength(6)]),
rememberMe: new FormControl()
});
}
save(model: User, isValid: boolean) {
console.log("Test");
console.log(model, isValid);
}
// Login in user
login(email: any, password: any){
this.ls.login(email, password, false);
}
}
Page.html
<div id="login-page">
<div class="form-wrapper">
<form class="login-form" [formGroup]="loginForm" novalidate (ngSubmit)="save(loginForm.value, loginForm.valid)">
<div >
<div class="input-field col s12 center">
<p class="center login-form-text">Login page</p>
</div>
</div>
<div >
<div class="input-field col s12">
<input id="email" type="email">
<label class="center-align" for="email" formControlName="email">Email</label>
</div>
</div>
<div >
<div class="input-field col s12">
<input id="password" type="password">
<label class="center" for="password" formControlName="password">Password</label>
</div>
</div>
<div >
<div class="input-field col s12 m12 l12 login-text">
<input id="remember-me" type="checkbox" formControlName="rememberMe">
<label for="remember-me">Remember me</label>
</div>
</div>
<div >
<div class="input-field col s12">
<ahref="index.html">Login</a>
</div>
</div>
<div >
<div >
<p><a href="page-register.html">Register Now!</a></p>
</div>
<div >
<p><a href="page-forgot-password.html">Forgot password ?</a></p>
</div>
</div>
</form>
</div>
</div>
异常
EXCEPTION: Uncaught (in promise): Error: Error in ./LoginComponent class LoginComponent - inline template:13:45 caused by: No value accessor for form control with name: 'email'.....
您正在将 formControlName
添加到标签而不是输入。
你有这个:
<div >
<div class="input-field col s12">
<input id="email" type="email">
<label class="center-align" for="email" formControlName="email">Email</label>
</div>
</div>
试试这个:
<div >
<div class="input-field col s12">
<input id="email" type="email" formControlName="email">
<label class="center-align" for="email">Email</label>
</div>
</div>
同时更新其他输入字段。
在我的例子中,我使用了 Angular 表单和 contenteditable
元素,例如 div
并且之前遇到过类似的问题。
我编写了 ng-contenteditable 模块来解决这个问题。
对于带有 angular material 的 UnitTest angular 2,您必须在导入部分添加 MatSelectModule 模块。
import { MatSelectModule } from '@angular/material';
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CreateUserComponent ],
imports : [ReactiveFormsModule,
MatSelectModule,
MatAutocompleteModule,......
],
providers: [.........]
})
.compileComponents();
}));
如果您遇到此问题,那么
- formControlName 不在值访问器元素上。
- 或者您没有导入该元素的模块。
如果必须使用标签为formControl
。就像 Ant Design 的复选框一样。它可能会在 运行 测试时抛出此错误。您可以使用 ngDefaultControl
<label nz-checkbox formControlName="isEnabled" ngDefaultControl>
Hello
</label>
<nz-switch nzSize="small" formControlName="mandatory" ngDefaultControl></nz-switch>
您可以在标签中看到 formControlName ,删除它解决了我的问题
对于在 angular 9+
中遇到此问题的任何人如果您不声明您的组件或导入声明该组件的模块,也会遇到此问题。
让我们考虑一种情况,您打算使用 ng-select
但您忘记导入它 Angular 将抛出错误 'No value accessor...'
我在 Below stackblitz demo 中重现了这个错误。
在我的例子中,我使用的是 ionic,我试图用 jasmine karma 对 ion-input 进行单元测试。
运行 测试时,我在 karma 浏览器中收到无值访问器错误。所以我只是将 ngDefaultControl
添加到离子输入,它解决了问题。
<ion-input class="password" [(ngModel)]="user.password" name="password"
type="password" #pw="ngModel" required ngDefaultControl>
</ion-input>
对我来说,只有 ionic 日期选择器出现错误,我不得不将 IonicModule
导入我的延迟加载模块
constructor(
private cdr: ChangeDetectorRef,
@Optional()
@Self() public ngControl: NgControl,
) {
if (ngControl) {
ngControl.valueAccessor = this;
}
}
在我的例子中,将这一行添加到自定义控件(可重用)组件的构造函数中
if (ngControl) {
ngControl.valueAccessor = this;
}
对我来说,我在 angular 应用程序中使用 primeng 下拉菜单。 下拉模块未导入。
或
您需要将 formControlName="controlName"
移动到 <mat-radio-group>
包装器,而不是将其绑定到单个 <mat-radio-button>
元素
在某些情况下,您可能会错过将 NG_VALUE_ACCESSOR
添加到可重用组件中作为提供程序。
@Component({
selector: 'app-reusable',
templateUrl: './reusable.component.html',
styleUrls: ['./reusable.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ReusableComponent),
multi: true,
},
],
})