我创建了自定义单选按钮组件,需要将值传递给父表单。但是我收到了错误消息: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
答案 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
}
*/
]
})