Angular2 - 单选按钮绑定

时间:2015-08-07 13:56:17

标签: forms radio-button angular

我想在使用Angular 2的表单中使用单选按钮

Options : <br/>

1 : <input name="options" ng-control="options" type="radio" value="1"  [(ng-model)]="model.options" ><br/>

2 : <input name="options" ng-control="options" type="radio" value="2" [(ng-model)]="model.options" ><br/>

model.options初始值为1

加载页面时,不会检查第一个单选按钮,并且修改不会绑定到模型

任何想法?

17 个答案:

答案 0 :(得分:99)

使用 [value] =&#34; 1&#34; 代替值=&#34; 1&#34;

[(ngModel)]

修改

正如thllbrg&#34所建议的那样;对于角度2.1+使用[(ng-model)]而不是container-btn&#34;

答案 1 :(得分:60)

注意 - RC4中的单选按钮绑定现在是支持的功能 - 请参阅this answer

使用类似于CheckboxControlValueAccessor的自定义RadioControlValueAccessor的单选按钮示例(使用Angular 2 rc-1更新

App.ts

import {Component} from "@angular/core";
import {FORM_DIRECTIVES} from "@angular/common";
import {RadioControlValueAccessor} from "./radio_value_accessor";
import {bootstrap} from '@angular/platform-browser-dynamic';

@Component({
    selector: "my-app",
    templateUrl: "template.html",
    directives: [FORM_DIRECTIVES, RadioControlValueAccessor]
})
export class App {

    model;

    constructor() {
        this.model = {
            sex: "female"
        };
    }

}

template.html

<div>
    <form action="">
        <input type="radio" [(ngModel)]="model.sex"  name="sex" value="male">Male<br>
        <input type="radio" [(ngModel)]="model.sex"  name="sex" value="female">Female
    </form>

    <input type="button" value="select male" (click)="model.sex='male'">
    <input type="button" value="select female" (click)="model.sex='female'">
    <div>Selected Radio: {{model.sex}}</div>
</div>

radio_value_accessor.ts

import {Directive, Renderer, ElementRef, forwardRef} from '@angular/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/common';

export const RADIO_VALUE_ACCESSOR: any = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() => RadioControlValueAccessor),
    multi: true
};

@Directive({
   selector:
       'input[type=radio][ngControl],input[type=radio][ngFormControl],input[type=radio][ngModel]',
   host: {'(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()'},
   bindings: [RADIO_VALUE_ACCESSOR]
})
export class RadioControlValueAccessor implements ControlValueAccessor {
   onChange = (_) => {};
   onTouched = () => {};

   constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}

   writeValue(value: any): void {
       this._renderer.setElementProperty(this._elementRef.nativeElement, 'checked', value == this._elementRef.nativeElement.value);
   }
   registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
   registerOnTouched(fn: () => {}): void { this.onTouched = fn; }
}

来源:https://github.com/angular2-school/angular2-radio-button

Plunker现场演示:http://plnkr.co/edit/aggee6An1iHfwsqGoE3q?p=preview

答案 2 :(得分:42)

我的手动解决方法,包括在选择新的单选按钮时手动更新model.options

template: `
  <label *ngFor="let item of radioItems">
    <input type="radio" name="options" (click)="model.options = item" 
     [checked]="item === model.options">
    {{item}}
  </label>`

class App {
  radioItems = 'one two three'.split(' ');
  model      = { options: 'two' };
}

Plunker 演示了上述内容,以及如何使用按钮更改所选单选按钮 - 即,证明数据绑定是双向的:< / p>

<button (click)="model.options = 'one'">set one</button>

答案 3 :(得分:36)

这是在Angular2中使用单选按钮的最佳方法。无需使用(click)事件或RadioControlValueAccessor来更改绑定属性值,设置[checked]属性就可以了。

<input name="options" type="radio" [(ngModel)]="model.options" [value]="1"
       [checked]="model.options==1" /><br/>
<input name="options" type="radio"  [(ngModel)]="model.options" [value]="2"
       [checked]="model.options==2" /><br/>

我发布了使用单选按钮的示例: Angular 2: how to create radio buttons from enum and add two-way binding? 它至少起作用于Angular 2 RC5。

答案 4 :(得分:18)

此问题分别以表格形式在Angular 2.0.0-rc.4版本中解决。

在package.json中包含"@angular/forms": "0.2.0"

然后在main中扩展你的引导程序。相关部分:

...
import { AppComponent } from './app/app.component';
import { disableDeprecatedForms, provideForms } from '@angular/forms';

bootstrap(AppComponent, [
    disableDeprecatedForms(),
    provideForms(),
    appRouterProviders
]);

我在.html中有这个并且完美地工作: 值:{{buildTool}}

<form action="">
    <input type="radio" [(ngModel)]="buildTool" name="buildTool" value="gradle">Gradle <br>
    <input type="radio" [(ngModel)]="buildTool" name="buildTool" value="maven">Maven
</form>

答案 5 :(得分:6)

我一直在寻找合适的方法来处理这些单选按钮,这是我在这里找到的解决方案的一个例子:

<tr *ngFor="let entry of entries">
    <td>{{ entry.description }}</td>
    <td>
        <input type="radio" name="radiogroup" 
            [value]="entry.id" 
            (change)="onSelectionChange(entry)">
    </td>
</tr>

注意将当前元素传递给方法的 onSelectionChange

答案 6 :(得分:4)

似乎还不支持无线电输入。 应该有一个无线电输入值访问器(类似于复选框的one,它设置'已检查'attr here)但我没有找到任何。所以我实施了一个;你可以查看here

答案 7 :(得分:4)

[数值] =&#34;项目&#34;使用* ngFor也适用于Angular 2和4中的Reactive Forms

acl=bucket-owner-full-control

答案 8 :(得分:2)

这是一个适合我的解决方案。它涉及单选按钮绑定 - 但不绑定到业务数据,而是绑定到单选按钮的状态。它可能不是新项目的最佳解决方案,但适合我的项目。我的项目有大量用不同技术编写的现有代码,我将其移植到Angular。旧代码遵循一种模式,其中代码非常有兴趣检查每个单选按钮以查看它是否是所选单选按钮。解决方案是点击处理程序解决方案的一种变体,其中一些已经在Stack Overflow上提到过。 此解决方案的附加值可能是:

  
      
  1. 使用我必须使用的旧代码模式。
  2.   
  3. 我创建了一个帮助器类来尝试减少“if”语句的数量    在单击处理程序中,并处理任何一组单选按钮。
  4.   

此解决方案涉及

  
      
  1. 为每个单选按钮使用不同的模型。
  2.   
  3. 使用单选按钮的模型设置“checked”属性。
  4.   
  5. 将单击的单选按钮的模型传递给帮助程序类。
  6.   
  7. 帮助程序类可确保模型是最新的。
  8.   
  9. 在“提交时间”,这允许旧代码检查的状态     单选按钮,通过检查模型来查看选择了哪一个。
  10.   

示例:

<input type="radio"
    [checked]="maleRadioButtonModel.selected"
    (click)="radioButtonGroupList.selectButton(maleRadioButtonModel)"

...

 <input type="radio"
    [checked]="femaleRadioButtonModel.selected"
    (click)="radioButtonGroupList.selectButton(femaleRadioButtonModel)"

...

当用户单击单选按钮时,辅助类的selectButton方法 被调用。它被传递了点击的单选按钮的模型。 helper类将传入模型的布尔“selected”字段设置为true,并将所有其他单选按钮模型的“selected”字段设置为false。

在初始化期间,组件必须构造一个helper类的实例,其中包含组中所有单选按钮模型的列表。在该示例中,“radioButtonGroupList”将是辅助类的实例,其代码为:

 import {UIButtonControlModel} from "./ui-button-control.model";


 export class UIRadioButtonGroupListModel {

  private readonly buttonList : UIButtonControlModel[];
  private readonly debugName : string;


  constructor(buttonList : UIButtonControlModel[], debugName : string) {

    this.buttonList = buttonList;
    this.debugName = debugName;

    if (this.buttonList == null) {
      throw new Error("null buttonList");
    }

    if (this.buttonList.length < 2) {
      throw new Error("buttonList has less than 2 elements")
    }
  }



  public selectButton(buttonToSelect : UIButtonControlModel) : void {

    let foundButton : boolean = false;
    for(let i = 0; i < this.buttonList.length; i++) {
      let oneButton : UIButtonControlModel = this.buttonList[i];
      if (oneButton === buttonToSelect) {
        oneButton.selected = true;
        foundButton = true;
      } else {
        oneButton.selected = false;
      }

    }

    if (! foundButton) {
      throw new Error("button not found in buttonList");
    }
  }
}

答案 9 :(得分:1)

最简单的解决方案和解决方法:

<input name="toRent" type="radio" (click)="setToRentControl(false)">
<input name="toRent" type="radio" (click)="setToRentControl(true)">

setToRentControl(value){
    this.vm.toRent.updateValue(value);
    alert(value); //true/false
}

答案 10 :(得分:1)

我通过在加载的元素上使用click事件并将选择的值传递给函数&#34; getSelection&#34;来创建一个版本。并更新模型。

在你的模板中:

<ul>
     <li *ngFor="let p of price"><input type="radio" name="price"      (click)="getValue(price.value)" value="{{p}}" #price> {{p}} 
     </li>
</ul>

你的班级:

export class App {

  price:string;

  price = ["1000", "2000", "3000"];

  constructor() {   }

  model = new SomeData(this.price);

  getValue(price){
    this.model.price = price;
  }
}

参见示例:https://plnkr.co/edit/2Muje8yvWZVL9OXqG0pW?p=info

答案 11 :(得分:1)

根据您的使用情况,这个答案可能不是最好的,但它确实有效。使用<select> </select>完美地保存和编辑,而不是使用单选按钮进行男性和女性选择。

<select formControlName="gender" name="gender" class="">
  <option value="M">Male</option>
  <option value="F">Female</option>
</select>

上面应该没问题,使用带有patchValue的FormGroup进行编辑。要进行创建,您可以使用[(ngModel)]代替formControlName。仍然有效。

与单选按钮一起涉及的管道工作,我选择了选择。在视觉和用户体验方面,它看起来并不是最好的,但从开发人员的角度来看,它更容易。

答案 12 :(得分:1)

以下内容解决了我的问题,请考虑在form标签内添加单选输入,并使用[value]标签显示该值。

<form name="form" (ngSubmit)="">
    <div *ngFor="let item of options">
        <input [(ngModel)]="model.option_id" type="radio" name="options" [value]="item.id"> &nbsp; {{ item.name }}
    </div>
</form>

答案 13 :(得分:1)

Angular 8广播列表示例:

来源Link

enter image description here

JSON响应

    [
            {
                "moduleId": 1,
                "moduleName": "Employee",
                "subModules":[
                    {
                        "subModuleId": 1,
                        "subModuleName": "Add Employee",
                        "selectedRightType": 1,
                    },{
                        "subModuleId": 2,
                        "subModuleName": "Update Employee",
                        "selectedRightType": 2,
                    },{
                        "subModuleId": 3,
                        "subModuleName": "Delete Employee",
                        "selectedRightType": 3,
                    }
                ]
            },  
            {
                "moduleId": 2,
                "moduleName": "Company",
                "subModules":[
                    {
                        "subModuleId": 4,
                        "subModuleName": "Add Company",
                        "selectedRightType": 1,
                    },{
                        "subModuleId": 5,
                        "subModuleName": "Update Company",
                        "selectedRightType": 2,
                    },{
                        "subModuleId": 6,
                        "subModuleName": "Delete Company",
                        "selectedRightType": 3,
                    }
                ]
            },  
            {
                "moduleId": 3,
                "moduleName": "Tasks",
                "subModules":[
                    {
                        "subModuleId": 7,
                        "subModuleName": "Add Task",
                        "selectedRightType": 1,
                    },{
                        "subModuleId": 8,
                        "subModuleName": "Update Task",
                        "selectedRightType": 2,
                    },{
                        "subModuleId": 9,
                        "subModuleName": "Delete Task",
                        "selectedRightType": 3,
                    }
                ]
            }
    ]

HTML模板

        <div *ngFor="let module of modules_object">
            <div>{{module.moduleName}}</div>
            <table width="100%">

                <thead>
                    <tr>
                        <th>Submodule</th>
                        <th>
                            <input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="1"> Read Only
                        </th>
                        <th>
                            <input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="2"> Read Write
                        </th>
                        <th>
                            <input type="radio" name="{{module.moduleName}}_head_radio" [(ngModel)]="module.selHeader" (change)="selAllColumn(module)" [value]="3"> No Access
                        </th>
                    </tr>
                </thead>

                <tbody>
                    <tr *ngFor="let sm of module.subModules">
                        <td>{{sm.subModuleName}}</td>
                        <td>
                            <input type="radio" [checked]="sm.selectedRightType == '1'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="1"> 
                        </td>
                        <td class="cl-left">
                            <input type="radio" [checked]="sm.selectedRightType == '2'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="2"> 
                        </td>
                        <td class="cl-left">
                            <input type="radio" [checked]="sm.selectedRightType == '3'" [(ngModel)]="sm.selectedRightType" name="{{sm.subModuleId}}_radio" [value]="3"> 
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

答案 14 :(得分:0)

这是我使用的一些可用于Angular 7的代码

(注意:过去,我有时会使用AnthonyBrenelière的答案提供的信息,对此我表示赞赏。但是,至少对于Angular 7,这部分内容是

 [checked]="model.options==2"

我发现没有必要。)

这里的解决方案具有三个优点:

  1. 与最常用的推荐解决方案一致。因此对新项目很有用。
  2. 还允许单选按钮代码类似于Flex / ActionScript代码。这一点很重要,因为我正在将Flex代码转换为Angular。像Flex / ActionScript代码一样,它允许代码在单选按钮对象上工作,以检查或取消选中或找出是否已选中单选按钮。
  3. 与您将看到的大多数解决方案不同,它非常基于对象。组织的一个优点是:组织:将单选按钮的数据绑定字段组合在一起,例如已选中,已启用,可见以及其他可能的字段。

示例HTML:

       <input type="radio" id="byAllRadioButton"
                 name="findByRadioButtonGroup"
                 [(ngModel)]="findByRadioButtonGroup.dataBindingValue"
                 [value]="byAllRadioButton.MY_DATA_BINDING_VALUE">         

      <input type="radio" id="byNameRadioButton"
                 name="findByRadioButtonGroup" 
                 [(ngModel)]="findByRadioButtonGroup.dataBindingValue"
                 [value]="byNameRadioButton.MY_DATA_BINDING_VALUE">

TypeScript示例:

 findByRadioButtonGroup : UIRadioButtonGroupModel
    = new UIRadioButtonGroupModel("findByRadioButtonGroup",
                                  "byAllRadioButton_value",
                                  (groupValue : any) => this.handleCriteriaRadioButtonChange(groupValue)
                                  );

  byAllRadioButton : UIRadioButtonControlModel
    = new UIRadioButtonControlModel("byAllRadioButton",
    "byAllRadioButton_value",
    this.findByRadioButtonGroup) ;

  byNameRadioButton : UIRadioButtonControlModel
    = new UIRadioButtonControlModel("byNameRadioButton",
    "byNameRadioButton_value",
    this.findByRadioButtonGroup) ;



  private handleCriteriaRadioButtonChange = (groupValue : any) : void => {

    if ( this.byAllRadioButton.selected ) {

      // Do something

    } else if ( this.byNameRadioButton.selected ) {

      // Do something

    } else {
      throw new Error("No expected radio button selected");
    }
  };

使用了两个类:

单选按钮组类别:

export class UIRadioButtonGroupModel {


  private _dataBindingValue : any;


  constructor(private readonly debugName : string,
              private readonly initialDataBindingValue : any = null,   // Can be null or unspecified
              private readonly notifyOfChangeHandler : Function = null       // Can be null or unspecified
  ) {

    this._dataBindingValue = initialDataBindingValue;
  }


  public get dataBindingValue() : any {

    return this._dataBindingValue;
  }


  public set dataBindingValue(val : any) {

    this._dataBindingValue = val;
    if (this.notifyOfChangeHandler != null) {
      MyAngularUtils.callLater(this.notifyOfChangeHandler, this._dataBindingValue);
    }
  }



  public unselectRadioButton(valueOfOneRadioButton : any) {

    //
    // Warning: This method probably never or almost never should be needed.
    // Setting the selected radio button to unselected probably should be avoided, since
    // the result will be that no radio button will be selected.  That is
    // typically not how radio buttons work.  But we allow it here.
    // Be careful in its use.
    //

    if (valueOfOneRadioButton == this._dataBindingValue) {
      console.warn("Setting radio button group value to null");
      this.dataBindingValue = null;
    }
  }

};

单选按钮类

export class UIRadioButtonControlModel {


  public enabled : boolean = true;
  public visible : boolean = true;


  constructor(public readonly debugName : string,
              public readonly MY_DATA_BINDING_VALUE : any,
              private readonly group : UIRadioButtonGroupModel,
              ) {

  }


  public get selected() : boolean {

    return (this.group.dataBindingValue == this.MY_DATA_BINDING_VALUE);
  }


  public set selected(doSelectMe : boolean) {

    if (doSelectMe) {
      this.group.dataBindingValue = this.MY_DATA_BINDING_VALUE;
    } else {
      this.group.unselectRadioButton(this.MY_DATA_BINDING_VALUE);
    }
  }

}

答案 15 :(得分:0)

在单选按钮更改时,获取各个按钮的值 这些行

<label class="radio-inline">
<input class="form-check-input" type="radio" [(ngModel)]="dog" name="cat"  checked (change)="onItemChange($event)" value="Dog" />Dog</label>
<label class="radio-inline">
<input class="form-check-input" type="radio" [(ngModel)]="cat" name="cat"   (change)="onItemChange($event)" value="Cat"  />Cat</label>

https://stackblitz.com/edit/angular-jpo2dm?embed=1&file=src/app/app.component.html

答案 16 :(得分:-1)

这可能不是正确的解决方案,但这个也是选项希望它能帮到某人。

直到现在我已经使用(点击)方法获得了radioButtons的值,如下所示:

<input type="radio" name="options" #male (click)="onChange(male.value)">Male
<input type="radio" name="options" #female (click)="onChange(female.value)">Female

在.ts文件中我已将预定义变量的值设置为onChange函数的getter值。

但是在搜索之后我发现了一个很好的方法我还没试过但看起来这个很好用[(ng-model)]链接到github here。这是使用RadioControlValueAccessor收音机以及复选框。这是方法的工作#plnkr#here