【问题标题】:Angular adding form controls to reactive formsAngular 将表单控件添加到反应式表单
【发布时间】:2018-09-01 14:08:14
【问题描述】:

我试图在选择单选选项是时需要一个 textarea,但它确实可以工作

如果我选择是,我会得到

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>

我还尝试将&amp;&amp; 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');
      }
    });
  }

【问题讨论】:

    标签: angular typescript angular6 angular-forms angular-validation


    【解决方案1】:

    您可以订阅'csc_dynamicsecurity' formControl valueChanges,而不是观察form valueChanges。那应该可以解决您的错误。在form.valueChanges 中添加新的formControls 可能会导致无限循环,从而导致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');
          }
        });
      }
    

    看到这个工作code

    【讨论】:

    • 非常感谢.. 它完美,它就像一个魅力。这篇文章让我失望了stackoverflow.com/questions/48729092/…
    • 链接中的解决方案对您不起作用,因为您错过了if 的第二个条件。在您的情况下,没有理由关注整个 form。你只关心电台form control的值。
    • 不确定我是否需要接受答案 感谢您指出这一点
    【解决方案2】:

    我根据@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'));
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      • 2021-02-05
      • 2021-01-12
      相关资源
      最近更新 更多