我正在尝试创建一个自定义组件,以这种方式组合一些Radio Buttonn
<group>
<radio></radio>
<radio></radio>
<radio></radio>
</group
在组件内部,我为dinamycly添加了输入的名称,因此它们都具有相同的名称,并在我点击另一个时更改所选的名称。
如果我只有一个组件,它的效果很好,如果我有多个组件,它会扩展值,就像它只是一组只有一个名称的RadioButtons一样。
这是我正在使用的代码:
import {AfterViewInit, Component, ContentChildren, ElementRef, Input, NgModule, QueryList} from "@angular/core";
import {CommonModule} from "@angular/common";
import {ControlValueComponent} from "../shared/ControlValueComponent";
import {SysSharedModule} from "../shared/SysSharedModule";
@Component({
selector: 'sys-radio-button',
styleUrls: ['sysRadioButton.css', '../shared/sys.css'],
providers: ControlValueComponent.providerValueAcessor(SysRadioButton),
template: `
<input type="radio" id="rb{{randomId}}" [value]="val" [(ngModel)]="value">
<label for="rb{{randomId}}">{{label}}</label>
`
})
export class SysRadioButton extends ControlValueComponent {
constructor (public elem: ElementRef) {
super();
}
@Input() groupName = 'radiobutton';
@Input() val: any;
@Input() label: string;
randomId = (Math.floor(Math.random() * (1 - 10000 + 1)) + 1) * -1;
}
@Component({
selector: 'sys-radio-group',
styleUrls: ['sysRadioButton.css', '../shared/sys.css'],
providers: ControlValueComponent.providerValueAcessor(SysRadioGroup),
template: `
<div class="t{{tam}}">
<label class="header">{{header}}</label>
<div class="radioButtonContainer"></div>
</div>
`
})
export class SysRadioGroup extends ControlValueComponent implements AfterViewInit {
@Input() name: string;
@Input() header: string;
@Input() tam = '3-of-10';
@ContentChildren(SysRadioButton) radioButtons: QueryList<SysRadioButton>;
constructor (public elem: ElementRef) {
super();
}
ngAfterViewInit() {
this.addNameToInputs();
}
addNameToInputs() {
const container = this.elem.nativeElement.getElementsByClassName('radioButtonContainer')[0];
this.radioButtons.forEach(item => {
const input = item.elem.nativeElement;
input.getElementsByTagName('input')[0].name = this.name;
container.appendChild(input);
});
}
}
@NgModule({
imports: [CommonModule, SysSharedModule],
declarations: [SysRadioButton, SysRadioGroup],
exports: [SysRadioButton, SysRadioGroup]
})
export class SysRadioButtonModule {
}
我这样用它:
<sys-radio-group header="Select your destiny" name="name1">
<sys-radio-button val="hola1" label="Label 1"></sys-radio-button>
<sys-radio-button val="hola2" label="Label 2"></sys-radio-button>
<sys-radio-button val="hola3" label="Label 3"></sys-radio-button>
<sys-radio-button val="hola4" label="Label 4"></sys-radio-button>
</sys-radio-group>
<sys-radio-group header="Select your destiny" name="name2">
<sys-radio-button val="hola1" label="Label 1"></sys-radio-button>
<sys-radio-button val="hola2" label="Label 2"></sys-radio-button>
<sys-radio-button val="hola3" label="Label 3"></sys-radio-button>
<sys-radio-button val="hola4" label="Label 4"></sys-radio-button>
</sys-radio-group>
以下是一些如何运作的图片
如果我检查chrome控制台中的元素,我可以看到名称是如何不同的,所以我不明白为什么会发生这种情况
修改
扩展主类的ControlValueComponent类只是自定义表单的类。这是代码:
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from "@angular/forms";
import {forwardRef, Input} from "@angular/core";
export class ControlValueComponent implements ControlValueAccessor {
@Input() disabled: boolean;
innerValue: any = '';
static providerValueAcessor( ref: any): any {
return [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ref), multi: true }
];
}
onTouchedCallback: () => void = () => {};
onChangeCallback: (_: any) => void = () => {};
constructor() {
}
get value(): any {
return this.innerValue;
}
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
writeValue(value: any) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: any): void {
this.onTouchedCallback = fn;
}
}
所以这里是[(ngModel)]的“value”变量来自
答案 0 :(得分:1)
将ngModel更改为:
[(ngModel)]="val"