Angular2自定义无线电按钮不起作用



我已经创建了自定义无线电按钮组件,需要将值传递给父表单。但是我收到了错误消息: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

改变了一些事情:

  • 使用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
    }
    */
  ]
})

最新更新