Angular2-单选按钮绑定


120

我想在使用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

加载页面时,未选中第一个单选按钮,并且修改未绑定到模型

任何想法 ?


Answers:


108

使用[value] =“ 1”代替value =“ 1”

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

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

编辑:

如thllbrg所建议:“对于有角度的2.1+,请使用[(ngModel)]而不是[(ng-model)]


7
ng-control属性的目的是什么?看起来如果没有它,一切都会起作用。
星期一

4
在Angular 4+中,您必须使用[(ngModel)]代替[(ng-model)]再读一次
克劳迪奥·霍兰达

1
这仅适用于添加新模式。在编辑模式下不起作用。我找不到原因。在新打开的模型工作分配值中,但是当我从服务器检索值并在屏幕中显示时,该值不起作用。
Vinoth Kumar

4
就我而言,我最终使用value="1" [(ngModel)]="model.options"。将value方括号括起来不起作用
Sylvan D Ash

2
很奇怪,但就我而言,我也不得不使用value =“ 1”而不是[value] =“ 1”。我正在使用Angular 6
–codingbbq

61

注意-单选按钮绑定现在是RC4及更高版本中受支持的功能 -请参见此答案

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

应用程式

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


4
以同样的方式,问题应该包括相关代码的问题,答案也应该这样。从理论上讲,这可能会回答该问题,但是最好在此处为将来的用户包括答案的基本部分,并提供链接以供参考。链接主导的答案可以通过link rot变为无效。
Mogsdad

很好..很奇怪,它没有包含在框架中
Mourad Zouabi

很好的解决方案!一个小的补充:我正在使用css input [type =“ radio”]:检查样式,但这仅对我有效,当使用_elementRef的nativeElement而不是_elementRef时: this._renderer.setElementProperty(this._elementRef.nativeElement, 'checked', value == this._elementRef.nativeElement.value);
bas

2
@GregWoods用新的更改更新了帖子,并感谢拉动请求,
Nidin Vinayakan

1
现在使用rc4及更高版本的角度提供了本机支持
-Ckln

45

我的手动解决方法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演示了上述内容,以及如何使用按钮来更改选定的单选按钮-即证明数据绑定是双向的:

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

我有两个问题。第一:在get debug()功能上get代表什么?第二个是:复选框是否有类似此答案的替代方法?请提供一些复选框代码。感谢+1很好的答案。
Pardeep Jain

2
@PardeepJain getTypeScript访问器功能。为复选框发布问题。
Mark Rajcok '16

可以像这样'{{debug(abc)}}'发送参数吗?
Pardeep Jain

1
@PardeepJain,请参阅plnkr.co/edit/iH3Te9EK7Y1dPXMzfWt6?p=preview。您不能像函数一样调用设置器,因此Anotherdate('2015-05-18T02:30:56')将无法使用。当您尝试为属性分配值时,将调用设置器。在我的监听器中,我创建了一个setDate()函数\ hat,它接受一个新的日期值,然后将其分配给Anotherdate。该分配将自动调用设置器。
Mark Rajcok '16

1
@PardeepJain,在{{}}每个更改检测周期都会重新评估绑定。我ngDoCheck()在插件中的AppComponent中实现了对更改检测周期的计数。由此可见,变更检测被称为3次。在开发人员模式下,绑定检查两次,因此检查了6次。
Mark Rajcok '16

36

这是在Angular2中使用单选按钮的最佳方法。无需使用(单击)事件或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/>

我发布了一个使用单选按钮的示例: 角度2:如何从枚举创建单选按钮并添加双向绑定? 它至少在Angular 2 RC5中运行。


2
这仅适用于添加新模式。在编辑模式下不起作用。我找不到原因。在新打开的模型工作分配值中,当我从服务器检索值并显示在屏幕中时不工作
Vinoth Kumar

1
@VinothKumar您设法使编辑模式起作用吗?我遇到了同样的问题
Dave Nottage '18

18

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

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

然后在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>

从rc4开始,这是正确的答案,仅此而已,收音机可以与枚举一起使用。
罗恩

8
运行RC7,我需要在[值]周围放置方括号
Brian Vander Plaats

1
我认为您需要使用括号,因为使用您的组件变量而不是字符串,在我的情况下,@ Zolcsi的答案很好!
Naeem Baghi's

1
这部分带有disableDeprecatedFormsprovideForms看起来很神奇,没有任何意义。这些东西是做什么的?这是冗余的无法读取的代码,使未知规模的事物无法预测。
Gherman'9

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


4

似乎尚不支持无线电输入。应该有一个无线电输入值存取(类似于复选框的一个,在那里设置“检查” ATTR 这里),但我没有发现任何。所以我实现了一个;您可以在这里查看



@JimB:不幸的是,似乎原生语言的语义是不同的
Kiara Grouwstra

4

使用* ngFor的[value] =“ item”也可用于Angular 2和4中的Reactive Forms

<label *ngFor="let item of items">
    <input type="radio" formControlName="options" [value]="item">
    {{item}}
</label>`

1
单选怎么办??
贝尔特

4

以下内容解决了我的问题,请考虑在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>

3

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

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

该解决方案涉及

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

例:

<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。

在初始化期间,组件必须使用该组中所有单选按钮模型的列表构造帮助器类的实例。在示例中,“ 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");
    }
  }
}

2

Angular 8 Radio列表示例:

链接

在此处输入图片说明

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>

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
}

2
在这种情况下,您如何从一开始就将单选按钮设置为默认值?
EricC '16

也可能会出现用户经常更改选择的情况,每一个检查都会执行一个函数,这是
blackHawk

1

我通过仅在加载的元素上使用click事件并将选择的值传递到函数“ getSelection”并更新模型来创建版本。

在您的模板中:

<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


1

根据您的用例,这个答案可能不是最好的,但它确实可行。与其使用单选按钮进行男性和女性选择,还<select> </select>可以完美地使用作品,进行保存和编辑。

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

对于将FormGroup与一起使用进行编辑,以上效果应该很好patchValue。对于创建,您可以使用[(ngModel)]而不是formControlName。仍然有效。

单选按钮涉及的水暖工作,我选择了选择。从视觉上和UX角度看,它似乎并不是最好的,但是从开发人员的角度来看,这要容易得多。


1

在单选按钮更改上,使用这些行获取相应按钮的值

<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


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">

示例打字稿:

 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);
    }
  }

}

-1

这可能不是正确的解决方案,但是这也是一种选择,希望对您有所帮助。

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

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

在.ts文件中,我将预定义变量的值设置为onChangefunction的getter值。

但是在搜索之后,我发现了一种好的方法,但我还没有尝试过,但是使用[(ng-model)]链接到这里的 github 似乎这是一种好的方法。这也RadioControlValueAccessor用于收音机和复选框。这里是工作#plnkr#这种方法在这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.