Сценарий
У нас есть кнопка «Далее» в шаговом компоненте. Кнопка должна быть отключена до тех пор, пока форма не будет действительна.
Подход
В AppStateService
создайте два свойства Observable
:
onFormChanged$:Observable<boolean>
isFormValid:Observable<boolean>
onFormChange
$
Этот наблюдаемый уведомляет об изменениях формы.
isFormValid
$
Это Observable
уведомляет нас о том, действительна ли форма.
Реализация Slice OStore Observable
const ON_FORM_CHANGE = 'ON_FORM_CHANGE' const IS_FORM_VALID = 'IS_FORM_VALID' constructor() { this.ostore.post(ON_FORM_CHANGE, false) this.ostore.post(IS_FORM_VALID, false) this.onFormChanged
$:Observable<boolean>
= this.ostore. observe(ON_FORM_CHANGE) this.isFormValid
$:Observable<boolean>
= this.ostore. observe(IS_FORM_VALID) }
Метод уведомления об изменении формы утилиты
Создайте служебный метод, который запускает уведомления об изменении формы:
emitFormChanged() { this.ostore. put(ON_FORM_CHANGE, true) }
Звоните onFormChanged()
всякий раз, когда форма изменяется:
this.form.valueChanges.pipe(untilDestroyed(this)). subscribe(()=>{ this.state.onFormChanged() })
Реагировать на изменения формы
Внутри AppStateService
создайте служебный метод, который переключает isFormValid$
:
toggleIsFormValid(valid:boolean) { this.ostore.put(IS_FORM_VALID, valid) }
Внутри ActionService
создайте действие, которое заставит isFormValid$
уведомлять:
enableParameterFormNextButton() { this.state.emitFormChanged$. pipe(untilDestroyed(this)).subscribe(()=>{ this.state.toggleIsFormValid( this.formService.form.valid) }) }
И, наконец, включите или отключите кнопку при срабатывании isFormValid$
:
<button matStepperNext [disabled]="!(state.isFormValid
$ | async)"
mat-button>Next</button>
Резюме
Теперь у нас есть возможность обновить любую точку в приложении о том, является ли форма действительной или измененной.
Эти события могут запускаться вне контекста приложения. Весь код, который мы реализовали, находится в AppStateService
и ActionService
, и поэтому модуль, тестирующий триггеры событий и соответствующие действия, становится простым. Мы могли бы создавать все наши события вне какой-либо среды приложения (React, Angular, Vue и т. д.) и просто вставлять события в триггеры событий пользовательского интерфейса.