как получить выбранное значение радио в реактивной форме

Я пытаюсь получить selectedValue переключателя и передать его как истину с помощью радиотекста. selectedValue для отправки как true, если выбран Choice 1, иначе false. И selectedValue будет отправлено как true, если выбран вариант 2, иначе false. Я не мог установить его в true. Было интересно, делал ли кто-нибудь это раньше?

https://stackblitz.com/edit/angular-xfrezb


person David Jeyathilak    schedule 27.01.2018    source источник


Ответы (2)


Прежде всего, всегда включайте соответствующий код в свой вопрос в виде блоков кода, поскольку ссылки со временем умирают...

Но что касается вашего вопроса, поскольку вы имеете дело с несколькими вопросами и динамическим value, я бы передал текущий formArray components и текущий answer. Сначала вам нужно будет установить все элементы управления формой selectedValue как false, поскольку в противном случае переключение каждого переключателя в конечном итоге превратилось бы в true щелчка по каждому из них. Итак, сначала установив все как false, просто установите выбранный переключатель как true. Итак, сделайте что-то вроде этого:

<div *ngIf="question.controls.type.value === 'radio'">
  <p>{{ question.controls.label.value }}</p>
  <div formArrayName="component">
    <div *ngFor="let answer of question.controls.component.controls; 
                 let j = index" [formGroupName]="j">
      <label>
        <input type="radio" name="radio-stacked" 
           (click)="updateSelection(question.controls.component.controls, answer)">
          <span>{{ answer.value.value }}</span>
      </label>
    </div>
  </div>
</div>

Тогда ваш метод updateSelection:

updateSelection(formArr, answer) {
  formArr.forEach(x => {
    x.controls.selectedValue.setValue(false);
  });
  answer.controls.selectedValue.setValue(true);
}

Ваш разветвленный StackBlitz

PS, что вы могли бы, конечно, рассмотреть, так это не иметь все варианты в вашем объекте формы, а просто добавить значение выбранного вами переключателя.

person AJT82    schedule 27.01.2018
comment
Спасибо, Алекс! Это потрясающе, именно то, что я искал. Не знал, что я должен использовать setValue. Мне нужно отправить все варианты выбора в объект формы... чтобы бэкэнд-разработчики Java знали точный выбор и выбранное значение для обновления базы данных... Еще раз спасибо! - person David Jeyathilak; 28.01.2018
comment
Добро пожаловать! Да, всегда устанавливая значения для форм элементов управления, нам нужно использовать setValue. Или, если у вас есть, например, группа форм и вы хотите просто установить некоторые значения, принадлежащие этой группе форм, вы можете использовать patchValue: this.myForm.patchValue({ ... }), если вы должны были использовать setValue в том же сценарии, вам нужно предоставить все значения для элементов управления формы в этом формагруппа. Но да, рад слышать, что это решение было жизнеспособным для вас! :) Хорошего окончания выходных :) - person AJT82; 28.01.2018
comment
Привет, @Alex. Большое спасибо за вашу помощь в выборе значения радио. Я не смог заставить то же самое работать с выпадающим списком. Не могли бы вы помочь? stackoverflow.com/questions/48517602/ - person David Jeyathilak; 30.01.2018

Вы смешиваете представление презентации и значение формы. Я думаю, что лучше разделить понятия. Мы можем использовать formObj для создания презентации и callbackForm для значения. Смотрите комментарии в коде

//приложение.main.html

<form [formGroup]="callbackForm" (submit)=submit(callbackForm)>
  <div>
    <div formArrayName="componentDetails">
        <div *ngFor="let question of callbackForm.controls.componentDetails.controls; let i = index;" [formGroupName]="i">
            <div class="row">
                <div class="col-md-12 panel-group panel-group--compressed">
                    <div class="panel panel--default">
                        <fieldset>
<!--see that we create the "view of the form using formObj.componentDetails--!>
                            <div class="row" *ngIf="formObj.componentDetails[i].type === 'radio'">
                                <div class="col-md-12">
                                    <p>{{ formObj.componentDetails[i].label }}</p>
                                    <p>{{ formObj.componentDetails[i].cpv }}</p>
<!-- we iterate throught "formObj.componentDetails[i].component -->
<!-- again, we are using formObj to the "view" -->
                                    <div *ngFor="let answer of formObj.componentDetails[i].component; let j = index">
                                       <label class="radio radio--alt radio--stacked">
                                            <span class="radio__input"></span>
                                             <span class="radio__label">{{ answer.value }}</span>
                                        </label>
<!--We have a input with name=formObj.componentDetails[i].cpv -->
<!--it's necesary enclose between {{ }} the name -->
                                        <input type="radio" formControlName="{{formObj.componentDetails[i].cpv}}" [value]="answer.selectedValue">
                                    </div>
                                </div>
                            </div>
                        </fieldset>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<button type="submit">send</submit>
</form>
<pre>{{callbackForm.value | json}}</pre>

//приложение-main.component

@Component({
  selector: 'app-app-main',
  templateUrl: './app-main.component.html'

})
export class AppMainComponent {

  constructor(private _formBuild: FormBuilder) {}

  ngOnInit() {
    this.loadObservableForm();
  }

  public callbackForm: FormGroup;

  formObj = {
    "componentDetails": [{
      "component": [{
        "value": "Choice 1",
        "selectedValue": true
      }, {
        "value": "Choice 2",
        "selectedValue": false
      }],
      "cpv": "name1",  //<--we use this to create the name of the fileld
      "label": "Description of Problem",
      "type": "radio",
      "mandatory": true
    }]
  };

  loadObservableForm() {
    this.callbackForm = this._formBuild.group({
      componentDetails: this._formBuild.array([])
    });
    this.addComponentDetails();
  }

  addComponentDetails() {
    const control = <FormArray>this.callbackForm.controls.componentDetails;
    this.formObj.componentDetails.forEach(x => {
      control.push(this.addControl(x));
    });
  }

  addControl(x) {
    //we create a group control with a control with a name "x.cpv"
    const group = this._formBuild.group({});
    group.addControl(x.cpv,new FormControl());
    return group;
  }

У нас есть callbackForm вида "componentDetails": [{"name1": false},{"name2":value2}...]. Итак, в submit мы можем сделать что-то вроде

submit(form)
{
   if (form.valid)
   {
       let response:any={}
       for (let control of form.value.componentDetails)
          response={...response,...control}

       console.log(response);
   }
}
person Eliseo    schedule 27.01.2018
comment
Спасибо, Элисео. Это интересная концепция разделения formObj и callbackForm. Я также попробую это. - person David Jeyathilak; 28.01.2018