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;
}
我正在尝试在 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;
}