RadioButtons表现奇怪的Angular 4

时间:2017-11-08 19:25:51

标签: javascript angular typescript radio-button components

我正在尝试创建一个自定义组件,以这种方式组合一些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>

以下是一些如何运作的图片

这是我没有点击任何东西的方式 enter image description here

这就是当我点击具有相同值但名称不同的一个时的外观 enter image description here

如果我检查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”变量来自

1 个答案:

答案 0 :(得分:1)

将ngModel更改为:

 [(ngModel)]="val"