【问题标题】:angular2 rc.5 custom input, No value accessor for form control with unspecified nameangular2 rc.5 自定义输入,未指定名称的表单控件的无值访问器
【发布时间】:2016-12-21 20:26:18
【问题描述】:

我有这样的简单自定义输入组件,

import {Component, Provider, forwardRef} from "@angular/core";
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";

const noop = () => {};

const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomInputComponent),
  multi: true
};

@Component({
  selector: 'custom-input',
  template: `

          <input class="form-control" 
                 [(ngModel)]="value" name="somename"
                 (blur)="onTouched()">

  `,
  providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class CustomInputComponent implements ControlValueAccessor{

  //The internal data model
  private _value: any = '';

  //Placeholders for the callbacks
  private _onTouchedCallback: () => void = noop;

  private _onChangeCallback: (_:any) => void = noop;

  //get accessor
  get value(): any { return this._value; };

  //set accessor including call the onchange callback
  set value(v: any) {
    if (v !== this._value) {
      this._value = v;
      this._onChangeCallback(v);
    }
  }

  //Set touched on blur
  onTouched(){
    this._onTouchedCallback();
  }

  //From ControlValueAccessor interface
  writeValue(value: any) {
    this._value = value;
  }

  //From ControlValueAccessor interface
  registerOnChange(fn: any) {
    this._onChangeCallback = fn;
  }

  //From ControlValueAccessor interface
  registerOnTouched(fn: any) {
    this._onTouchedCallback = fn;
  }

}

我有这样的应用程序模块,

/**
 * Created by amare on 8/15/16.
 */
import { NgModule }                     from '@angular/core';
import { BrowserModule }                from '@angular/platform-browser';
import { ReactiveFormsModule, FormsModule }          from '@angular/forms';
import { AppComponent }                 from './app/app.component';
import {CustomInputComponent} from "./app/shared/custom.input.component";
import {RouterModule} from "@angular/router";
@NgModule({
  imports: [ BrowserModule, ReactiveFormsModule, FormsModule, RouterModule ],
  declarations: [ AppComponent, CustomInputComponent],
  bootstrap: [ AppComponent ]
})
export class AppModule {  
}

和主要的

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }              from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

并且我已经在我的一个组件中使用了我的自定义输入,如下所示,但我得到“没有用于具有未指定名称属性的表单控件的值访问器”。

<custom-input name="firstName" [(ngModel)]="firstName"></custom-input>

app.component 看起来像这样

import { Component } from '@angular/core';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  title = 'app works!';

  firstName: string;
}

【问题讨论】:

  • 我对实现 ControlValueAccessor 的自定义指令有同样的问题。它在 RC4 中工作,但在 RC5 中出现与您相同的错误。希望有人有解决方案。
  • 尝试将ngDefaultControl 添加到您的控件中,如下所示:&lt;custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl&gt;&lt;/custom-input&gt;
  • @danieleds 非常感谢它就像一个魅力,即使 Angular 团队没有回应。
  • 当心您可能正在使用的任何第 3 方包 - 如果您导入任何使用旧的 FORM_DIRECTIVES 的东西,它会破坏您的应用程序!例如:github.com/valor-software/ng2-charts/issues/352
  • 对我来说,在 [(ngModel)]="...." 工作之前添加 ngDefaultControl

标签: angular


【解决方案1】:

将 ngDefaultControl 添加到主机中的自定义输入组件解决了这个问题,感谢@danieleds

【讨论】:

  • 这个解决方案对我不起作用。我有一个名称应用于我的input,我还尝试将ngDefaultControl 添加到输入中,但它不起作用。仍然给了我同样的错误。在 RC5 中
  • 同意,我在 html 和 ngDefaultControl 中添加了 name 属性,我使用了 formControl,但它不起作用。
  • 查看关于 ngDefaultControl 工作原理的非常好的解释 - stackoverflow.com/a/46465959/968003。本质上,它添加了默认的ControlValueAccessor,它充当了 Angular 表单 API 和 DOM 中的原生元素之间的桥梁。
【解决方案2】:

将 ngDefaultControl 添加到自定义输入组件。这增加了双向数据绑定,除非您正在做一些独特的事情,否则您不必实现值访问器方法。

<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>

【讨论】:

    【解决方案3】:

    ngDefaultControl 添加到您的输入中。例如

    <inline-editor type="textarea" [(ngModel)]="editableTextArea" (onSave)="saveEditable($event)" value="valor" ngDefaultControl> </inline-editor> 
    

    然后import { FORM_DIRECTIVES } from '@angular/common';

    最终指令:[FORM_DIRECTIVES]

    这会起作用 :) 感谢上述 cmets

    【讨论】:

    • 请使用反引号和其他markdown 命令使您的帖子更具可读性。
    • 我使用的是RC6,@angular/common中没有FORM_DIRECTIVES
    • NG2 FINAL 不再使用表单指令
    【解决方案4】:

    我将[(ngModel)] 放在我的&lt;option&gt; 标签上,而不是&lt;select&gt;

    所以是的......这会导致这个。

    【讨论】:

    • 是的....我有同样的错误,将 ngModel 放在 而不是 上。呜呜呜……
    【解决方案5】:

    作为出现这种情况的另一种情况,我在最近重建和简化的自定义组件上指定了 [(ngModel)],而新版本的组件只是将 ngModel 作为带有发射的普通输入变量。

    这还不够 - 输入变量必须重命名为 ngModel 之外的其他名称,或者组件必须实现 ControlValueAccessor 接口 (see the docs for details)。一旦其中一个完成,您将不再收到此错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-30
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多