Связывание данных и состояния формы
Здравствуйте, вопрос заключается в следующем: я отслеживаю изменения в форме. И есть несколько вариантов решения:
1. Подписываемся на изменения во всей форме. В этом случае, при возникновении события необходимо проверить всю форму и в измененное поле внести новое значение. formSubm: Subscription; componentForm: FormGroup; componentData; initState() { this.componentForm = this.formBuilder.group({ code: new FormControl(""), name: new FormControl("", [Validators.required), date_modify: new FormControl(null), }); } ngOnInit() { this.initState(); this.formSubm = this.componentForm.valueChanges .subscribe(value => { this.applyFormValues(value) }); } applyFormValues(item) { Object.keys(item).forEach(key => { if (this.componentData[key] != item[key]) this.componentData[key] = item[key]; }); } ngOnDestroy() { if (this.formSubm) { this.formSubm.unsubscribe(); } } <form [formGroup]="componentForm" (ngSubmit)="formSubmit()"> <div> <mat-form-field> <input formControlName="code" matInput> </mat-form-field> <mat-form-field> <input formControlName="name" matInput> </mat-form-field> <mat-form-field> <input formControlName="date_modify" matInput> </mat-form-field> </div> <button type="submit"> <ng-template>Сохранить</ng-template> </button> </form> Второе решение, подписываться на изменения каждого из полей. При этом инициализацию, конечно, можно вогнать в цикл и при выходе из компонента отписываться от всех подписок, но волнует вопрос большого количества подписок. ngOnInit() { this.$s1 = this.componentForm.get('name').valueChanges.subscribe(res => { this.ctrl.name.setValue(res, { emitEvent: false }); this.componentData['name'] = res; }); this.$s2 = this.componentForm.get('code').valueChanges.subscribe(res => { this.ctrl.code.setValue(res, { emitEvent: false }); this.componentData['code'] = res; }); this.$s3 = this.componentForm.get('date_modify').valueChanges.subscribe(res => {this.ctrl.date_modify.setValue(res, { emitEvent: false }); this.componentData['date_modify'] = res; }); } Третий вариант -- создать одну универсальную функцию и вешать ее как обработчик: <mat-form-field> <mat-label>Код</mat-label> <input formControlName="code" matInput (keyup)="onChange($event, 'code')"> </mat-form-field> onChange(e: KeyboardEvent, field: string) { if (e.key == "Enter") return false; this.componentForm.controls[field].setValue((<HTMLInputElement>e.target).value); this.componentData[field] = (<HTMLInputElement>e.target).value; } Какой вариант по вашему более оптимален с точки зрения производительности? |
shtangen,
зачем всё это писать в переменную componentData, если это же самое хранится в componentForm.value ? |
В componentData хранится определенный тип
componentData = new PostTemplate(<IPostTemplate>{}); ngOnInit() { this.ctrl = this.componentForm.controls; this.dataService.getItem<PostTemplate>(this.currId) .subscribe((data: PostTemplate) => { this.componentData = new PostTemplate(data); this.ctrl.code.setValue(data.code); this.ctrl.name.setValue(data.name); this.ctrl.date_modify.setValue(data.date_modify); }); } Описание типа почтовое уведомления: /** * Почтовое уведомление * * @export * @interface IPostTemplate */ export interface IPostTemplate { /** Id */ id?: string; /** Код почтового уведомления */ code: string; /** Название почтового уведомления */ name: string; /** Дата изменения */ date_modify?: string; /** Флаг активен или нет */ active?: string; /** Флаг текст или нет */ is_text?: string; /** Титул */ title?: string; /** Контент */ content?: string; } Класс почтового уведомления: export class PostTemplate implements IPostTemplate { id?: string; code: string; name: string; active?: string; is_text?: string; date_modify: string; title?: string; content?: string; constructor( data: IPostTemplate ) { this.id = data.id || undefined; this.code = data.code || ''; this.name = data.name || ''; this.date_modify = data.date_modify || ''; this.active = data.active || ''; this.is_text = data.is_text || ''; } } |
Думаю первый вариант - это ок. Кстати, можно вызвать componentForm.setValue(data), вместо того чтобы устанивливать значения для каждого из контролов отдельно.
|
Спасибо, за хорошее замечание, код допилил. :thanks:
|
Часовой пояс GMT +3, время: 05:36. |