Reputation:
I use a component with reactive form in a tab. Each time when I switch the tab, the validator of my component will be called once more. This is my component:
import { Component, forwardRef, OnInit } from "@angular/core";
import {
AbstractControl,
FormBuilder,
FormGroup,
NG_VALIDATORS,
NG_VALUE_ACCESSOR,
ValidationErrors,
Validator,
Validators
} from "@angular/forms";
@Component({
selector: "app-my-form",
templateUrl: "./my-form.component.html",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MyFormComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MyFormComponent),
multi: true
}
]
})
export class MyFormComponent implements Validator, OnInit {
public form: FormGroup;
constructor(fb: FormBuilder) {
this.form = fb.group({
name: [null, Validators.required]
});
}
// ControlValueAccessor
public writeValue(value: any): void {
if (value) {
this.form.patchValue(value, { emitEvent: false });
}
if (value === null) {
this.form.reset();
}
}
public registerOnChange(fn: any): void {
this.form.valueChanges.subscribe(fn);
}
public registerOnTouched(fn: any): void {
this.onTouched = fn;
}
public setDisabledState?(isDisabled: boolean): void {
isDisabled ? this.form.disable() : this.form.enable();
}
// ControlValueAccessor end
// Validator
validate(control: AbstractControl): ValidationErrors {
console.log("validate");
return null;
}
// Validator end
public onTouched: () => void = () => {};
ngOnInit() {}
}
I also made a stackblitz: https://stackblitz.com/edit/angular-tab-test-hx71jy?file=src%2Fapp%2Fmy-form%2Fmy-form.component.ts
what am I doing wrong?
Upvotes: 1
Views: 601
Reputation: 27471
The issue is because of memory leak in formControlName directive. As a workaround you can set destroyOnHide input property to false, so that it will hide the component instead of destroying.
<form [formGroup]="form">
<ul ngbNav #nav="ngbNav" [(activeId)]="active" class="nav-tabs">
<li [ngbNavItem]="1" [destroyOnHide]="false">
<a ngbNavLink>One</a>
<ng-template ngbNavContent>
<app-my-form formControlName="tab1"></app-my-form>
</ng-template>
</li>
<li [ngbNavItem]="2">
<a ngbNavLink>Two</a>
<ng-template ngbNavContent>
<p>
Lorem ipsum
</p>
</ng-template>
</li>
</ul>
</form>
Upvotes: 1