表单控件没有值访问器

154

我正在使用Angular2-rc5,但我目前在登录页面上遇到了一个错误。我试图创建一个表单,但控制台抛出异常,告诉我它找不到我的formcontroll,尽管我在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); 
    }
}

页面.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>

异常

异常:未处理的(在promise中):错误:错误发生于./LoginComponent类-内联模板:13:45,原因是:表单控件'name'为'email'没有值访问器......


1
在我的情况下,我给出了组件的错误名称。例如:<p-multiselect... 而不是 <p-multiSelect... - Alfaz Jikani
13个回答

207
你将formControlName加在了

3
对我来说也是同样的问题,因为我在 span 标签上应用了 formControlName。谢谢! - Anh Hoang
4
我甚至在一个自定义组件中遇到了这个问题,该组件具有 @Input formControl。在一个地方,formControl 被正确地传递给了我的组件,在另一个地方出现了上述错误。最终,我将 formControl 输入重命名为其他不同的名称。如果没有这个答案,我就永远找不到这个问题 :/ - Pieter De Bie
2
我也给这个解决方案点赞 - 我正在使用一个<mat-form-field>元素,并将formControlName应用于它(但不起作用)。将其移动到包含的<mat-select>元素中完美地解决了这个问题! - Ade
我在option标签中使用了ngModel,所以我将它移到了select标签中,然后它就起作用了。谢谢! - José Ripoll
2
我曾经遇到过同样的问题(在测试和实际组件中分别出现),因为我在自定义元素上使用了表单控件名称,但我忘记导入该元素的模块,这阻止了表单控件的正确绑定。 - Rov
如何在“材料复选框”中应用此解决方案? - meDeepakJain

87

对于使用Angular Material的单元测试 (UnitTest) ,您需要在导入部分中添加MatSelectModule模块。

import { MatSelectModule } from '@angular/material';

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ CreateUserComponent ],
      imports : [ReactiveFormsModule,        
        MatSelectModule,
        MatAutocompleteModule,......

      ],
      providers: [.........]
    })
    .compileComponents();
  }));

2
非常感谢,我添加了MatCheckboxModule并解决了我的问题。 - Mahdi
不要导入整个模块,而是使用 ng-mocks 模拟该组件。 - chrisjsherm

70

对于任何在Angular 9+中遇到此问题的人

如果您没有声明组件或导入声明组件的模块,也可能出现此问题。

让我们考虑这样一种情况,您想要使用ng-select,但忘记将其导入,Angular 将会抛出错误“没有值访问器...”

我已在下面的 stackblitz 演示中重现了此错误


2
一个更好的答案是提供一个已解决的演示,而不是重新制造相同的错误。 - Lenzman
7
@Lenzman,我认为解决方案已经很明确了。这个答案是为了帮助那些可能由于没有导入特定组件而遇到此问题的人。如果你认为这不是你在SO上寻找的解决方案,或者期望其他人在这里找到不同的解决方案,欢迎你提供你的解决方案。 - Owen Kelvin
1
@OwenKelvin,对我来说解决方案不太清楚。导入什么东西在哪里?谢谢。 - Adam M. Costello

31

如果您遇到此问题,则可能是以下原因之一:

  • formControlName未定位在值访问元素上。
  • 或者您没有为该元素导入模块。

1
在我的情况下,我在调用TestBed.configureTestingModule时从导入中缺少了MyDatePickerModule。 - tschumann
1
缺少元素模块的导入。这很有帮助! - Father-Empire
或者组件在其自己的模块中没有出现在声明和导出中。 - lilalinux

14

如果您必须使用formControl的标签,就像Ant Design Checkbox一样。在运行测试时可能会出现此错误。您可以使用ngDefaultControl

<label nz-checkbox formControlName="isEnabled" ngDefaultControl>
    Hello
</label>

<nz-switch nzSize="small" formControlName="mandatory" ngDefaultControl></nz-switch>

在这里更新另一种更好的方法:https://dev59.com/2VMI5IYBdhLWcg3wDXHj#73327822 - Phat Tran

8

在我的情况下,我正在使用ionic,并尝试使用jasmine karma对ion-input进行单元测试。在运行测试时,在karma浏览器中会出现没有值访问器错误。因此,我只需在ion-input中添加ngDefaultControl即可解决问题。

<ion-input class="password" [(ngModel)]="user.password" name="password" 
                type="password" #pw="ngModel" required ngDefaultControl>
</ion-input>

我有两个不同的项目,使用相同的框架版本,其中一个需要ngDefaultControl,而另一个没有它也能正常工作。很奇怪。 - ScottN
我进行了重构,现在我的ionic表单需要ngDefaultControl。不确定为什么。 - Quethzel Díaz

8
在某些情况下,您可能会忘记将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,
        },
    ],
})

7

或者

您需要将formControlName="controlName"移至<mat-radio-group>包装器,而不是将其绑定到单个<mat-radio-button>元素(S)。


5

我在 Angular 应用中使用了 PrimeNG 下拉菜单。

但是,下拉菜单模块没有被导入。


遇到了完全相同的问题。谈论误导性的错误信息。 - The Head Rush
非常感谢,我想不出哪里有问题了。 - John H

4

enter image description here

enter image description here

你可以看到label标签中有formControlName属性,移除这个属性可以解决我的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接