angle2 rc.5カスタム入力、名前が指定されていないフォームコントロールの値アクセサーなし


80

私はこのような単純なカスタム入力コンポーネントを持っています、

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);

以下に示すように、コンポーネントの1つでカスタム入力を使用しましたが、「名前属性が指定されていないフォームコントロールの値アクセサーがありません」というメッセージが表示されます。

<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の場合と同じエラーが発生します。誰かが解決策を持っていることを願っています。
user2444499 2016

38
追加してみてくださいngDefaultControl:これは次のように、あなたのコントロールに<custom-input name="firstName" [(ngModel)]="firstName" ngDefaultControl></custom-input>
danieleds

@danieledsは、角度のあるチームが応答していなくても、魅力のように機能することに感謝します。
アマレ2016

1
使用している可能性のあるサードパーティのパッケージに注意してください。古いものを使用しているものをインポートFORM_DIRECTIVESすると、アプリが破損します。適切な
ピート

私にとっては、[(ngModel)] = "...."が機能する前にngDefaultControlを追加しました
themightysapien 2017

回答:


73

ホストのカスタム入力コンポーネントにngDefaultControlを追加すると、問題が解決しました。@ danieledsに感謝します。


8
この解決策は私にはうまくいきませんでした。名前を適用しましたが、入力にinput追加しようとしngDefaultControlましたが、機能しませんでした。それでも同じエラーが発生しました。RC5の場合
prolink007

2
同意します。htmlとngDefaultControlにnameプロパティを追加しましたが、formControlを使用しましたが、機能しません。
スティーブK

1
どのようにngDefaultControl機能するかについての非常に良い説明を参照してください-stackoverflow.com/a/46465959/968003。基本的に、デフォルトを追加しますControlValueAccessor。これは、Angular FormsAPIとDOMのネイティブ要素の間のブリッジとして機能します。
Alex Klaus

46

カスタム入力コンポーネントにngDefaultControlを追加します。これにより、双方向のデータバインディングが追加されます。独自の処理を行わない限り、値アクセサーメソッドを実装する必要はありません。

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

12

ngDefaultControl入力に追加します。例えば

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

次にimport { FORM_DIRECTIVES } from '@angular/common';

最後にディレクティブ: [FORM_DIRECTIVES]

これはうまくいくでしょう:)上記のコメントをありがとう


2
markdown投稿を読みやすくするために、バッククォートやその他のコマンドを使用してください。
buhtz 2016

4
私は、RC6を使用して、そこではないのですFORM_DIRECTIVES@angular/common
Kosmonaft

6
フォームディレクティブはNG2FINALではなくなりました
Steve K

4

私は身に着け[(ngModel)]ていた<option>代わりにタグ<select>

そうそう...それはこれを引き起こすでしょう。


うん....同じエラーが発生し、ngModelを<mat-radio-group>ではなく<mat-radio-button>に配置しました。Grrrrrr ....
マイクGledhill

0

これが発生するさらに別のシナリオとして、[(ngModel)]最近再構築および簡略化されたカスタムコンポーネントを指定しました。コンポーネントの新しいバージョンは、emitを使用ngModelした通常の入力変数として持っていました。

これでは不十分でした。入力変数の名前を、以外ngModelに変更するか、コンポーネントにControlValueAccessorインターフェイスを実装する必要があります(詳細についてはドキュメントを参照してください)。どちらか一方が完了すると、このエラーは発生しなくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.