【问题标题】:Angular - Multiple Radio buttons in reactive formsAngular - 反应形式的多个单选按钮
【发布时间】:2019-04-05 17:06:40
【问题描述】:

我们有如下列表(在原始实现中 productList 将来自 API)

productList = [{
    productId: "104",
    productName: "computer"
  },
  {
    productId: "105",
    productName: "Sprots"
  },
  {
    productId: "106",
    productName: "TV"
  }];

我们需要将产品名称显示为 html 中的单选按钮,类似这样。

[] Computer
[] Sports
[] TV

当我们选择一个单选按钮时,它应该在组件中给出选定的项目(例如,如果我们选择电视单选按钮,可能是这样的?

this.myForm.controls['productMethods'].valueChanges.subscribe(value => {
      var a  = value 
      // how can i get a = { productId: "106",productName: "TV"} **?**
    }

对于预选:-

[] Computer
[x] Sports <== how to make sports as pre-selected on page load also **?**
[] TV

我尝试的是https://stackblitz.com/edit/angular-formarray-example-2-3xq45k,但未能显示单选按钮。

谢谢,

【问题讨论】:

  • 您的链接无效,您在*ngFor 中犯了错误,并在您的模板中添加formArrayName
  • @Abhishek - 当然,我会更新链接
  • @Abhishek - 已更新。

标签: angular angular6 angular-reactive-forms


【解决方案1】:

Here is an updated version of your Stackblitz.

首先,由于您使用的是无线电输入,因此您只会收到一个值,而不是一个数组。

this.productFormGroup = this.formBuilder.group({
  productMethod: new FormControl("105"),
});

其次,您的无线电输入必须具有相同的名称(该名称需要与formControlName 匹配)。

<input type="radio"
  formControlName="productMethod"
  id="radio{{i}}"
  name="productMethod"
  [value]=item>
<label class="custom-control-label"
  for="radio{{i}}">
  {{item.productName || '?'}}
</label>

第三,我不会使用对象作为表单值,因为您无法(轻松地)比较对象以设置默认值。使用productId,使用方法检索对应的产品。

getProductById(id): any {
  return this.productList.find(p => p.productId == id);
}

最后,我做了一些小改动,让你的代码更好一点。

<div [formGroup]="productFormGroup">
  <div *ngFor="let item of productList; let i = index;">
    <input type="radio"
      formControlName="productMethod"
      id="radio{{i}}"
      name="productMethod"
      [value]=item.productId>
    <label class="custom-control-label"
      for="radio{{i}}">
      {{item.productName || '?'}}
    </label>
  </div>
</div>
{{ getProductById(productFormGroup.controls.productMethod.value) | json }}

【讨论】:

  • 如何选择在加载页面加载或某些按钮事件时预先选择的“sprots”,请提供任何提示?
  • this.productFormGroup.controls["productMethod"].patchValue({ productId: "105", productName: "sprots" });
【解决方案2】:

有点晚了,但让我把这个留在这里。 角度材料有 mat-radio-group,在你的模块中,import {MatRadiomodule} from '@angular/material' 也将它导入到 @NgModule 中。

在你的component

this.formGroupVariable = this.fb.group({
    productItem: ['', Validators.required],
    . . .
});

然后在你的template component

<mat-radio-group *ngFor="let productItem of productList">
    <label for="{{productItem.value}}" class="radio-inline">
        <input id="{{productItem.value}}" 
               [value]="productItem.value"
               formControlName="productItem"                                          
               type="radio"
               name="requestType"
               [checked]="productItem.value==='Sports'">
               {{productItem.value}}
    </label>
</mat-radio-group>

我希望这会有所帮助。

【讨论】:

  • 感谢您的回复 - 但我们不喜欢使用有棱角的材料
  • @var,你可以用 div 元素替换 mat-radio-group 元素,你实际上仍然得到相同的结果。
【解决方案3】:

1.-你需要写“formArrayName”

2.-formControlName用[]括起来

3.-单选按钮???如果你想要单选按钮,它只是一个 formControlName,而不是一个数组

<div [formGroup]="productFormGroup">
    <!---you need write "formArrayName"--->
    <div formArrayName="productMethods">
        <div *ngFor="let item of productList; let i = index">
            <div>
                <!--formControlName is enclosed by []-->
                <input type="checkbox" name="{{'acceptable'+i}}" [formControlName]="i">
                <label class="custom-control-label" 
                    for="{{ 'acceptable' + i}}">{{item.productName}}
               </label>
           </div>
        </div>
    </div>
</div>

this.myForm.controls['productMethods'].valueChanges.subscribe(value => {
      //value becomes, e.g. [true,false,false]
      values.forEach((v,index)=>{
         if (v)
           console.log(productList[i]);
      })
    }

注意:如果你想要单选按钮

<div [formGroup]="productFormGroup">
    <div *ngFor="let item of productList; let i = index" >
        <input type="radio" name="product" formControlName="product" [value]="item" >
    <label class="custom-control-label" 
        for="{{ 'acceptable' + i}}">{{item.productName}}</label>
    {{item.productname}}
  </div>
</div>

但是你的表格是这样的

this.productFormGroup = this.formBuilder.group({
      product:''
    });

【讨论】:

  • 是的,我需要单选按钮(不是复选框),我会尝试更新 stackblitz。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
  • 2019-01-24
  • 2021-07-19
  • 2021-05-02
相关资源
最近更新 更多