Angular反应形式:动态生成单选按钮

时间:2020-09-12 03:28:35

标签: angular dynamic radio-button angular-reactive-forms

预期行为: 从json文件生成一组多项选择题。每个问题都应包含无线电输入形式的多个选项。您一次只能选择一个选项。

预期行为-

Expected Behavior

实际行为: 除非您单击单选按钮,然后单击另一个按钮,否则一切看起来都是正确的,并且不会取消选择上一个按钮。如果您继续单击并且不能取消选择任何一个,则最终可以选择每个选项。

实际行为-

Actual Behavior

代码明细: 它的基础是Review组件,我们在其中循环遍历一系列问题,并为每个问题生成一个Question组件。我们还将构建FormGroup并将其传递。每个Question组件都以完全相同的方式生成许多Option组件。每个选项组件都由一个int和一个<input type="radio">

组成

stackblitz.com/edit/angular-dynamically-generated-radio-buttons

观察: 在Option组件的html中,如果我从<label>中删除了[formControlName]="name",那么它可以纠正我遇到的问题,但这是Reactive Forms不可或缺的。我必须在这里特别地做错什么,但是对于我的一生,我无法弄清楚。就像每个选项一样,它的行为都有其自己的形式控制,或者至少我认为这会起作用。

在下面,您可以看到表单组的日志以及问题1:选项1&2的html。据我所知,这是应该的。请帮忙!

FormGroup的日志-

Log of FormGroup

问题1,选项1&2的html-

html of Question1, Options1&2

2 个答案:

答案 0 :(得分:0)

<div class="form-check" [formGroup]="form">
    <input class="form-check-input"  type="radio" [id]="id" [value]="option.letter" [name]="name" #op [formControlName]="name" >
    <label class="form-check-label" [for]="id" >
    {{option.text}}
  </label>
</div>

import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit, Renderer2 } from '@angular/core';
import { Question } from '../../models/question';
import { Option } from '../../models/option';
import { FormGroup } from '@angular/forms';

@Component({
  selector: 'app-option',
  templateUrl: './option.component.html',
  styleUrls: ['./option.component.scss']
})
export class OptionComponent implements OnInit, AfterViewInit {
  @Input() question: Question;
  @Input() option: Option;
  @Input() form: FormGroup;
  @ViewChild('op') op: ElementRef;
  id:string;
  name:string;

  constructor(
    private renderer: Renderer2
  ) { }

  ngOnInit() {
    this.id = `${this.question.number}${this.option.letter}`;
    this.name = `${this.question.number}`;
  }
  ngAfterViewInit() {
    this.renderer.setProperty(this.op.nativeElement, 'name', this.name);

  }
}

共享代码应该可以解决您的问题。

之所以发生这种情况,是因为出于某种原因,angular并没有在单选按钮上写入name属性。

所以这段代码明确地编写了它。

答案 1 :(得分:0)

Rahul的贴片效果很好,但是我最终要做的是只是切换到使用角形材料元素。事后看来,在使用Angular时使用Angular Material元素可能是一个好主意。但是对于那些无论出于何种原因都无法做到的人,他的解决方案行之有效。

这是我的带有角形材料的代码的样子:

OptionComponent html

<div>
  <mat-radio-button [value]="option.letter" >
    {{option.text}}
  </mat-radio-button>
</div>

QuestionComponent html

<div [formGroup]="form">
  <mat-radio-group [formControlName]="name">
    <label>{{question.label}}</label>
    <ng-template #options_anchor></ng-template>
  </mat-radio-group>
</div>