Angular2自定义单选按钮不起作用

时间:2017-02-20 07:38:38

标签: angular angular2-forms

我创建了自定义单选按钮组件,需要将值传递给父表单。但是我收到了错误消息:Cannot find control with unspecified name attribute

父模板:

<form #f="ngForm">
  <radio name="radioParent" [data]="data" ngDefaultControl [(ngModel)]="dataOut"></radio>
</form>

子组件:

import {
  Component, Input, forwardRef, ElementRef, Renderer
} from '@angular/core';
import {
  FormControl,
  NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlValueAccessor
} from '@angular/forms';


@Component({
    selector: 'radio',
    template: `
    <ul>
      <li *ngFor="let item of data">
        <label>
          <input type="radio" name="radio1"
            [value]="item.id"
            [formControl]="childControl"
            (input)="fn($event.target.value)"
            >
          <p>{{ item.title }}</p>
        </label>
      </li>
    </ul>
    `,
    providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyChild),
      multi: true
    },
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => MyChild),
      multi: true
    }
  ]
})

export class MyChild  implements ControlValueAccessor {
  @Input() data: any;
  out: any;


  fn: (value:any) => void;

  validateFn: any = () => {};

  constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}

  writeValue(value: any): void {
    this._renderer.setElementProperty(this._elementRef, 'checked', value == this._elementRef.nativeElement.value);
  }
  registerOnChange(fn: (value: any) => void) {
    this.onChange = fn;
  }
  registerOnTouched() {}

}

在plunker:https://plnkr.co/edit/hkk0CANKWRmys9R4gZg1?p=preview

1 个答案:

答案 0 :(得分:1)

更改了一些内容:

  • 使用item.value代替item.id
  • 已移除[formControl]="childControl",您的组件中没有属性childControl !!
  • 使用(click)代替(input)
  • 已移除provide: NG_VALIDATORS,会导致错误!你需要正确设置它,不要复制来自provide: NG_VALUE_ACCESSOR
  • 的粘贴

工作演示:https://plnkr.co/edit/iYQF2Z6MVh0aeMz1nGLG?p=preview

@Component({
    selector: 'radio',
    template: `
    <ul>
      <li *ngFor="let item of data">
        <label>

          <!-- [formControl]="childControl" causes errors.. there is no property called 'childControl' in this component.. -->
          <!-- [value]="item.value" instead of [value]="item.id" !! -->

          <input type="radio" name="radio1"
            [value]="item.value"

            (click)="onChange($event.target.value)">

          <!-- use (click) instead of (input) -->

          <span>{{ item.title }}</span>
        </label>
      </li>
    </ul>
    `,
    providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => MyChild),
      multi: true
    }
    /*, causes errors !!
    {
      provide: NG_VALIDATORS,
      //useExisting: forwardRef(() => MyChild), => not right !! do not just copy and paste stuff around .. !
      // should be something like this:
      useValue: validateEmail, // <-- your validation function !
      // see this article: https://blog.thoughtram.io/angular/2016/03/14/custom-validators-in-angular-2.html
      multi: true
    }
    */
  ]
})