#angular #ngrx
#angular #ngrx
Вопрос:
В приложении Angular 12 мы используем NgRx с ngrx-формами. Начальное FormGroupState выглядит следующим образом:
export const initialFormData = createFormGroupState<IFormData>('patientData', {
(..)
birthday: {
day: null,
month: null,
year: null,
},
(..)
});
Это FormGroupState встроено в состояние, которое содержит все другие данные состояния:
export const initialState: IState = {
(..),
formData: initialFormData,
(..)
};
Управление FormData осуществляется с помощью атрибутов в html-шаблоне компонента:
<mat-form-field>
<mat-label>Tag</mat-label>
<input matInput type="number" [ngrxFormControlState]="formState.controls.birthday.controls.day">
</mat-form-field>
<mat-form-field>
<mat-label>Monat</mat-label>
<select matNativeControl [ngrxFormControlState]="formState.controls.birthday.controls.month">
(..)
</select>
</mat-form-field>
<mat-form-field>
<mat-label>Jahr</mat-label>
<input matInput type="number" [ngrxFormControlState]="formState.controls.birthday.controls.year">
</mat-form-field>
Кроме того, formState реализован в основном редукторе NgRx:
const stateReducer = createReducer( initialState, onNgrxForms(), (..), );
Пока все работает по назначению, и любое обновление, которое пользователь вносит в эти поля формы, обновляется в состоянии:
Теперь, в одном экземпляре, мне нужно вручную установить это formState после действия пользователя (в данном случае, использование mat-календаря). Итак, я создал действие для этого случая, которое принимает год, месяц и день, каждый в виде числа:
export const setDateOfBirth = createAction('[PatientData] setDateOfBirth',
props<{ newYear: number, newMonth: number, newDay: number }>()
);
Реализация в редукторе выглядит следующим образом:
const stateReducer = createReducer(
initialState,
onNgrxForms(),
(..),
on(setDateOfBirth, (state, {newYear, newMonth, newDay}) => ({
...state,
formData: {
...state.formData,
value: {
...state.formData.value,
birthday: {...state.formData.value.birthday, year: newYear, month: newMonth, day: newDay}
}
},
})),
);
Это также работает нормально, и состояние устанавливается на любые реквизиты, которые я передаю редуктору:
Однако после установки значений вручную, как только любое другое изменение вносится в другое поле ввода, которое контролируется ngrx-form для этого formState, например, поле ввода для имени, formState мгновенно возвращается к последнему состоянию перед изменением вручную. Поле ввода выглядит следующим образом:
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput type="text" [ngrxFormControlState]="formState.controls.name">
</mat-form-field>
Я не уверен, почему это происходит, и, конечно, хотел бы предотвратить возврат к предыдущему состоянию. Если я запускаю несколько ручных настроек для formState, все они отменяются, как только [ngrxFormControlState] инициирует любое изменение формы.
Редактировать: я также нашел директиву ngrxFormsAction, которую, к сожалению, нельзя использовать с mat-calendar («Событие ngrxFormsAction не генерируется никакими применимыми директивами или элементом mat-calendar»).