【问题标题】:No value accessor for form control表单控件没有值访问器
【发布时间】:2017-04-25 12:37:26
【问题描述】:

我正在使用 Angular2-rc5,我目前在我的登录页面上遇到错误。我正在尝试制作一个表单,但控制台抛出异常告诉我它找不到我的formcontrolls,即使我在初始化时创建它。知道为什么我会收到此错误吗?

登录组件

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>

例外

异常:未捕获(承诺中):错误:./LoginComponent 中的错误 类 LoginComponent - 内联模板:13:45 原因:无值 具有名称的表单控件的访问器:'email'.....

【问题讨论】:

  • 就我而言,我给出的组件名称不正确。前任。

标签: javascript forms angular form-control


【解决方案1】:

您将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>

同时更新其他输入字段。

【讨论】:

  • 对我来说同样的问题,因为我将 formControlName 应用于 span 标签。谢谢!
  • 我什至在自定义组件中遇到了这个问题,该组件具有 @Input formControl。在一个地方,formControl 被正确地传递给我的组件,在另一个地方发生了上述错误。我最终将 formControl 输入重命名为不同的东西。如果没有这个答案,我永远不会找到这个:/
  • 我也为这个解决方案竖起了大拇指——我正在使用&lt;mat-form-field&gt; 元素,并且将formControlName 应用于该元素(没有用)。将其移动到包含的 &lt;mat-select&gt; 元素完美解决了这个问题!
  • 我在选项标签中使用了 ngModel,所以我将它移到了选择标签中并且它工作了。谢谢!
  • 我遇到了同样的问题(在测试和实际组件分开的时候),因为我在自定义元素上使用了表单控件名称,而我忘记为该元素导入模块,从而阻止了表单从适当的绑定控制。
【解决方案2】:

对于 UnitTest angular 2 with angular material,您必须在导入部分添加 MatSelectModule 模块。

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

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

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

【讨论】:

  • 非常感谢,我添加了 MatCheckboxModule 并解决了我的问题。
  • 不是导入整个模块,而是使用ng-mocks模拟组件
【解决方案3】:

对于在 angular 9+

中遇到此问题的任何人

如果您不声明组件或导入声明组件的模块,也会遇到此问题。

让我们考虑一种情况,您打算使用 ng-select 但您忘记导入它,Angular 会抛出错误“无值访问器...”

我已经在Below stackblitz demo 中重现了这个错误。

【讨论】:

  • 更好的答案是使用已解决的演示,而不是重新创建相同的错误
  • @Lenzman 我认为解决方案很明确。该答案旨在帮助因未导入特定组件而可能面临此问题的任何人。如果您认为这不是您正在寻找的解决方案或希望其他人在 SO 上找到,欢迎您提供您的解决方案
【解决方案4】:

如果你遇到这个问题,那么

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

【讨论】:

  • 在我的情况下,我在调用 TestBed.configureTestingModule 时缺少导入中的 MyDatePickerModule
  • 缺少该元素的模块导入。这有帮助!
【解决方案5】:

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

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

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

【讨论】:

    【解决方案6】:

    在我使用 ionic 的情况下,我尝试使用 jasmine karma 对离子输入进行单元测试。 运行测试时,我在 karma 浏览器中收到无值访问器错误。所以我只是将ngDefaultControl 添加到离子输入中,它解决了问题。

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

    【讨论】:

    • 我在同一个框架版本上有两个不同的项目,一个需要 ngDefaultControl,另一个没有它也能正常工作。很奇怪。
    【解决方案7】:

    在我的例子中,我使用带有contenteditable 元素的Angular 表单,比如div,之前也遇到过类似的问题。

    我写了ng-contenteditable 模块来解决这个问题。

    【讨论】:

      【解决方案8】:

      您可以在 label 中看到 formControlName ,删除它解决了我的问题

      【讨论】:

        【解决方案9】:

        对我来说,我只遇到了离子日期选择器的错误,我必须将 IonicModule 导入到我的延迟加载模块中

        【讨论】:

        • 对于 Ionic 用户,如果您在自定义组件中工作,这是解决方案。
        【解决方案10】:
            constructor(
            private cdr: ChangeDetectorRef,
            @Optional() 
            @Self() public ngControl: NgControl,
            ) {
        
            if (ngControl) {
                ngControl.valueAccessor = this;
              }
        
        }
        

        在我的例子中,将此行添加到自定义控件(可重用)组件的构造函数中

        if (ngControl) {
                ngControl.valueAccessor = this;
              }
        

        【讨论】:

          【解决方案11】:

          对我来说,我在 Angular 应用程序中使用了 primeng 下拉菜单。 未导入下拉模块。

          【讨论】:

          • 遇到了同样的问题。谈论误导性错误消息。
          【解决方案12】:

          您需要将 formControlName="controlName" 移动到 &lt;mat-radio-group&gt; 包装器,而不是将其绑定到单个 &lt;mat-radio-button&gt; 元素

          【讨论】:

            猜你喜欢
            • 2018-01-21
            • 2020-07-16
            • 1970-01-01
            • 1970-01-01
            • 2018-06-07
            • 1970-01-01
            • 1970-01-01
            • 2023-04-08
            • 1970-01-01
            相关资源
            最近更新 更多