IT

Angular2- 라디오 버튼 바인딩

lottoking 2020. 7. 14. 07:54
반응형

Angular2- 라디오 버튼 바인딩


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입니다.

페이지가로드되지 않은 첫 번째 라디오 버튼이 확인되지 않고 수정 사항이

어떤 아이디어?


사용 = "1"[값] 대신 값 = "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/>

편집하다 :

"각 2.1 사용을 위해 thllbrg에 의해 제안 [(ngModel)]대신 [(ng-model)]"


참고-라디오 버튼 바인딩은 이제 RC4부터 지원되는 기능 입니다. 이 답변을 참조하십시오

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

플 런커 라이브 데모 : http://plnkr.co/edit/aggee6An1iHfwsqGoE3q?p=preview


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>

Angular2에서 라디오 버튼을 사용하는 가장 좋은 방법은 다음과 같습니다. 바인딩 된 속성 값을 변경하기 위해 (클릭) 이벤트 또는 RadioControlValueAccessor를 사용할 필요가 없습니다. [체크] 속성을 설정하면 트릭이 수행됩니다.

<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 : enum에서 라디오 버튼을 양방향 바인딩을 추가하는 방법은 무엇입니까? Angular 2 RC5에서 작동합니다.


이 문제는 버전 Angular 2.0.0-rc.4에서 추가 형태로 해결되었습니다.

"@angular/forms": "0.2.0"package.json 포함에 하십시오 .

그런 다음 메인에서 부트를 확장하십시오. 관련 부분 :

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

여기에서 라디오 버튼을 처리하는 올바른 방법을 찾고 있습니다.

<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 를 확인하십시오.


라디오 입력이 아직 지원되지 않습니다. (체크 박스의 무선 입력 접근이 필요한 이 ATTR '확인'으로 설정, 여기 하지만 난 아무것도 발견하지 않았다). 그래서 나는 하나를 구현했다. 여기서 확인할 수 있습니다 .


* ngFor를 사용하는 [value] = "item"은 Angular 2 및 4의 반응 형이 작동합니다.

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

다음은 내 문제를 해결했습니다. 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>

다음은 나를 위해 작동하는 솔루션입니다. 여기에는 라디오 버튼이 있습니다. 아마도 새 프로젝트에 가장 비용 솔루션은 어떤 내 프로젝트에 적합합니다. 내 프로젝트에는 Angular로 포팅하는 다른 기술로 수많은 기존 코드가 있습니다. 이전 코드는 코드가 각 라디오 버튼을 검사하여 선택한 버튼인지 확인하는 데 매우 관심이있는 패턴을 나타냅니다. 이 솔루션은 클릭 솔루션의 변형으로, 일부는 이미 스택 이 솔루션의 부가 가치는 다음과 가변적입니다.

  1. 내가 오래된 오래된 코드 패턴으로 작동합니다.
  2. 클릭 할 수있는 "if"문의 수를위한 라디오 버튼 그룹을 처리하기 위해 도우미 클래스를 만들었습니다.

이 솔루션에는

  1. 각 라디오 버튼마다 다른 모델을 사용합니다.
  2. 라디오 버튼의 모델로 "checked"속성 설정
  3. 클릭 한 라디오 버튼의 모델을 도우미 클래스로 전달합니다.
  4. 도우미 클래스는 모델이 최신인지 확인합니다.
  5. "제출 시간"에서 이전 코드는 라디오 버튼의 상태를 검사하여 모델을 검사하여 선택 버튼을 확인할 수 있습니다.

예 :

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

...

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

...

사용자가 단일 선택 단추를 클릭하면 헬퍼 클래스의 selectButton 메소드가 호출됩니다. 클릭 한 라디오 버튼의 모델이 전달됩니다. 도우미 클래스는 전달 된 모델의 부울 "선택"필드를 true로 설정하고 다른 모든 단일 선택 단추 모델의 "선택"필드를 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");
    }
  }
}

가장 간단한 솔루션 및 해결 방법 :

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

로드 된 요소에 대해 클릭 이벤트 만 사용하고 선택 값을 "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


유스 케이스에 따라이 답변이 최선이 아닐 수도 있습니다. 남성과 여성의 선택에 라디오 버튼을 사용하는 대신 <select> </select>저장과 편집을 위해 작품을 완벽하게 사용하십시오 .

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

위와 함께 FormGroup을 사용하여 편집 위의 내용이 수행되어야합니다 patchValue. 만들기 위해 [(ngModel)]대신 사용할 수 있습니다 formControlName. 여전히 작동합니다.

라디오 버튼 하나와 관련된 배관 작업은 선택 대신에 선택했습니다. UX에서는 일반적으로 최고인 것 같지는 않지만 개발자의 입장에서는 있습니다.


다음은 Angular 7에서 작동하는 코드입니다.

(참고 : Anthony Breneliè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);
    }
  }

}

이 올바른 해결책이 아닐 수도 있습니다. 누군가에게 도움이되기를 희망하는 옵션이기도합니다.

지금까지 다음과 같은 (클릭) 방법을 사용하여 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에 있습니다 . 이것은 RadioControlValueAccessor라디오와 동일에도 사용됩니다. 여기이 방법에 대한 작업 # plnkr #이 있습니다 .

참고 URL : https://stackoverflow.com/questions/31879497/angular2-radio-button-binding

반응형