Angular добавление элементов управления формы в реактивные формы

Я пытаюсь иметь текстовое поле, необходимое, когда выбрана опция радио Да, но это работает

если я выберу Да, я получу

RangeError: превышен максимальный размер стека вызовов

если я выберу "нет", тогда "да" я получу

Не удается найти элемент управления с неопределенным атрибутом имени

import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {Router} from '@angular/router';
import {SorDataService} from '../sor-data.service';

@Component({
  selector: 'app-intervention-strategies',
  templateUrl: './intervention-strategies.component.html',
  styleUrls: ['./intervention-strategies.component.css']
})
export class InterventionStrategiesComponent implements OnInit {

  public form: FormGroup;

  /** Page 5 */
  constructor(public data: SorDataService, private formBuilder: FormBuilder, private router: Router) {
  }

  public ngOnInit() {

    this.form = this.formBuilder.group({
      csc_dynamicsecurity: [null, Validators.required],
    });

    this.form.valueChanges.subscribe(values => {

      if (values['csc_dynamicsecurity'] === true) {
        this.form.addControl('csc_dynamicsecurityexplanation', new FormControl('', Validators.required)); // Add new form control
      }
      else if (values['csc_dynamicsecurity'] === false) {
        this.form.removeControl('csc_dynamicsecurityexplanation');
      }
    });
  }

  public next() {

    if (this.form.valid) {
      alert('valid');
    }
  }
}

Попытка добавить проверку формы в поле, которое условно добавлено в форму

<form [formGroup]="form">

  <div class="app-radio-field app-field-required" [ngClass]="displayFieldCss('csc_dynamicsecurity')">

    <h5 i18n>Dynamic Security and Staff Presence?</h5>

    <mat-radio-group [formControl]="form.get('csc_dynamicsecurity')">
      <mat-radio-button color="primary" [value]="true"
                        i18n>Yes
      </mat-radio-button>

      <mat-radio-button color="primary" [value]="false"
                        i18n>No
      </mat-radio-button>
    </mat-radio-group>
  </div>

  <mat-form-field class="full-width" *ngIf="form.get('csc_dynamicsecurity').value === true">
  <textarea matTextareaAutosize matInput required i18n-placeholder placeholder="Explain"
            [formControl]="form.get('csc_dynamicsecurityexplanation')"></textarea>
  </mat-form-field>

</form>

Я также попытался добавить && this.form.get('csc_dynamicsecurityexplanation') к подписке, поскольку я отправил другие предложения, и это, похоже, исправляет ошибку стека, но я все еще получаю ошибку ниже .. Я не совсем уверен, что делаю это правильно ... любая помощь нужна

Не удается найти элемент управления с неопределенным атрибутом имени

    this.form.valueChanges.subscribe(values => {

      if (values['csc_dynamicsecurity'] === true && this.form.get('csc_dynamicsecurityexplanation')) {
        this.form.addControl('csc_dynamicsecurityexplanation', new FormControl('', Validators.required)); // Add new form control
      }
      else if (values['csc_dynamicsecurity'] === false && this.form.get('csc_dynamicsecurityexplanation')) {
        this.form.removeControl('csc_dynamicsecurityexplanation');
      }
    });
  }

person Ricardo Saracino    schedule 01.09.2018    source источник


Ответы (2)


Вместо того, чтобы наблюдать form valueChanges, вы можете подписаться на 'csc_dynamicsecurity' formControl valueChanges. Это должно исправить ваши ошибки. Добавление нового formControls в form.valueChanges может привести к бесконечному циклу и, следовательно, к RangeError: Maximum call stack size exceeded

 this.form.get('csc_dynamicsecurity').valueChanges.subscribe(values => {

      if (values === true) {
        this.form.addControl('csc_dynamicsecurityexplanation', new FormControl('', Validators.required), ); // Add new form control
      }
      else if (values === false) {
        this.form.removeControl('csc_dynamicsecurityexplanation');
      }
    });
  }

См. Этот рабочий код

person Amit Chigadani    schedule 01.09.2018
comment
Большое спасибо .. он идеален, он работает как шарм. это сообщение меня сбило с толку stackoverflow.com/questions/48729092/ - person Ricardo Saracino; 01.09.2018
comment
Это решение в ссылке не сработало для вас, потому что вы пропустили второе условие для if. В вашем случае нет причин смотреть весь form. Вас просто беспокоит значение радио form control. - person Amit Chigadani; 01.09.2018
comment
не был уверен, что мне нужно принять ответ, спасибо, что указали на это - person Ricardo Saracino; 01.09.2018

Я придумал общее решение проблемы, основанное на коде @Amit, надеюсь, что это поможет кому-то

public ngOnInit() {

    this.form = this.formBuilder.group({
      csc_dynamicsecurity: [null, Validators.required],
    });

    const fnBool = (input) => {
      return (value) => {
        if (value === true) {
          this.form.addControl(input, new FormControl('', Validators.required)); // Add new form control
        }
        else if (value === false) {
          this.form.removeControl(input);
        }
      };
    };

    this.form.get('csc_dynamicsecurity').valueChanges.subscribe(fnBool('csc_dynamicsecurityexplanation'));
  }
person Ricardo Saracino    schedule 01.09.2018