Показать сообщение отдельно
  #1 (permalink)  
Старый 22.11.2019, 10:46
Интересующийся
Отправить личное сообщение для shtangen Посмотреть профиль Найти все сообщения от shtangen
 
Регистрация: 21.08.2019
Сообщений: 11

Связывание данных и состояния формы
Здравствуйте, вопрос заключается в следующем: я отслеживаю изменения в форме. И есть несколько вариантов решения:

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;
}


Какой вариант по вашему более оптимален с точки зрения производительности?
Ответить с цитированием