ERROR RangeError: Maximum call stack size exceeded (Angular 6)

ERROR RangeError: Maximum call stack size exceeded (Angular 6)

我正在尝试在 angular 中使用嵌套反应式表单,并对每个字段进行验证。提交表格后,我正在检查字段。如果有任何错误,表单会显示它们并持续监听变化。现在,嵌套表单登录抛出 "Maximum stack call exceeded error"。我知道那是因为浏览器一直在调用 TS 文件中定义的 login() getter。谁能告诉我如何解决这个问题?

Error in console:
ERROR RangeError: Maximum call stack size exceeded
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:53)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)
    at VendorSignupComponent.get [as login] (vendor-signup.component.ts:54)

component.html:

<div class="container">
  <form [formGroup]="vendorSignupForm" (ngSubmit)="onSubmit()">

    <div class="form-group">
      <div class="row">
        <div class="col-sm-6 col-md-4">
          <label for="name">Restaurant Name</label>
          <input type="text" formControlName="name" class="form-control" pattern="[a-zA-z\s]+" [ngClass]="{'is-invalid': submitted && f.name.errors}" />
          <div *ngIf="submitted && f.name.errors" class="invalid-feedback">
            <div *ngIf="f.name.errors.required">Name is required</div>
            <div *ngIf="f.name.errors.pattern">Not a valid name!</div>
          </div>
        </div>
      </div>
    </div>

    <div class="form-group">
      <div class="row">
        <div class="col-sm-6 col-md-4">
          <label for="emailId">Email</label>
          <input type="email" formControlName="emailId" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.emailId.errors }" />
          <div *ngIf="submitted && f.emailId.errors" class="invalid-feedback">
            <div *ngIf="f.emailId.errors.required">Email is required</div>
            <div *ngIf="f.emailId.errors.email">Not a valid email!</div>
          </div>
        </div>
      </div>
    </div>

    <div formGroupName="login">
      <div class="form-group">
        <div class="row">
          <div class="col-sm-6 col-md-4">
            <label for="password">Password</label>
            <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && login.password.errors }" />
            <div *ngIf="submitted && login.password.errors" class="invalid-feedback">
              <div *ngIf="login.password.errors.required">Password is required</div>
              <div *ngIf="login.password.errors.minlength">Password must be at least 8 characters</div>
              <div *ngIf="login.password.errors.maxlength">Password cannot be more than 15 characters</div>
            </div>
          </div>
        </div>
      </div>
      ...
    </div>

component.ts:

export class VendorSignupComponent implements OnInit {

  submitted = false;
  vendorSignupForm: FormGroup;

  constructor(
    private formBuilder: FormBuilder,
    private router: Router
  ) {}

  ngOnInit() {
    this.vendorSignupForm = this.formBuilder.group({
      name: ['', Validators.required],
      emailId: ['', [Validators.required, Validators.email]],
      openingTime: ['', Validators.required],
      closingTime: ['', Validators.required],
      minDeliveryTime: ['', Validators.required],
      minOrder: ['', Validators.required],
      mainCuisineType: ['', Validators.required],
      imageUrl: ['', Validators.required],
      numOfTables: ['', Validators.required],
      category: ['', Validators.required],
      vendorRegistrationId: ['', Validators.required],
      vendorAddress: this.formBuilder.group({
        street: ['', Validators.required],
        city: ['', Validators.required],
        pincode: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(6)]],
        state: ['', Validators.required],
        phoneNumber: ['', [Validators.required, Validators.maxLength(10), Validators.minLength(10)]],
        landlineNumber: [''],
      }),
      login: this.formBuilder.group({
        password: ['', [Validators.required, Validators.minLength(8), Validators.maxLength(15)]],
        role: ['vendor']
      })
    });
  }

  get f() {
    return this.vendorSignupForm.controls;
  }

  get login() {
    return this.login.controls;
  }

  get vendorAddress() {
    return this.vendorAddress.controls;
  }

  onSubmit() {
    this.submitted = true;
    console.log(this.vendorSignupForm.value);

    if (this.vendorSignupForm.invalid) {
      return;
    }
  }
}

login 的 getter 内的行 this.login.controls 再次尝试调用相同的 getter 因为您尝试访问 this.login 导致递归。而且 this.login.controls 不会直接给你控件。您必须通过 vendorSignupForm 获取它,如下所示。

考虑重构您的 login getter,如下所示。

get login() {
    let login = this.vendorSignupForm.get('login') as FormGroup;
    return login.controls;
}