Как переписать приложения Angular, чтобы они стали практически наблюдаемыми и не требовали подписки
Управление подписками - одна из самых сложных частей работы с RxJS и Observables в Angular. Даже с такими помощниками, как async pipe, takeUntilDestroyed и auto-unsubscribe, легко столкнуться с ошибками и утечками памяти. Новая функция Signals в Angular призвана решить эту проблему, представив более простую модель реактивного программирования без подписки.
В сочетании с новой мощной библиотекой управления состояниями NgRx SignalStore мы можем переписать приложения Angular, сделав их практически наблюдаемыми и не требующими подписки. Недавно я сделал это на примере приложения LocalCast Weather из моей книги "Angular для корпоративных приложений" и хочу поделиться обзором.
Замена Observables на Promises и Signals
Первый ключ - заменить HTTP-ответы Observable и якоря данных BehaviorSubject на API, основанные на промисах. NgRx SignalStore использует сигналы для управления собственными подписками:
async getCurrentWeather(searchText, country) {
return promiseBasedWeatherApiCall();
}
Мы можем соединить оставшиеся Observables с помощью таких помощников, как:
import {toSignal} from '@angular/core'
const searchTerms$ = toSignal(termsObservable)
Нам также нужно установить стратегию обнаружения изменений на OnPush
, чтобы компоненты обновлялись только при изменении их входов:
@Component({
//...
changeDetection: ChangeDetectionStrategy.OnPush
})
Переход на управление состоянием SignalStore
NgRx SignalStore предлагает простой API для управления состоянием с помощью сигналов:
const store = signalStore(
withState({
currentWeather: initialWeather,
}),
withMethods((
store,
weatherService = inject(WeatherService)
) => ({
async updateWeather(search) => {
const weather = await apiCall(search)
patchState(store, {currentWeather: weather})
}
})
)
@Component({
template: `
{{store.currentWeather | json}}
`
})
export class WeatherComponent {}
Поэтому вместо того, чтобы загружать данные в сервисы и продвигать изменения через субъекты, методы хранилища компонентов получают данные и обновляют сигналы. Это позволяет инкапсулировать получение данных без промежуточных потоков. Компоненты просто привязываются к соответствующим сигналам состояния.
В результате получается гораздо более компактный код, не требующий явной обработки подписки. Мы получаем отличную эргономику, используя сигналы, и при этом централизуем логику управления состоянием с помощью SignalStore.
Готовность к будущему Angular на основе сигналов
В то время как Observables и RxJS предлагают огромную декларативную реактивную мощь, они также подразумевают определенные сложности. Сигналы призваны упростить реактивное программирование Angular. В сочетании с опциями управления состоянием, такими как NgRx SignalStore, мы можем исключить почти все подписки из наших приложений.
Заключение
На GitHub я выложил полный перенос приложения LocalCast Weather из "Angular для корпоративных приложений" в SignalStore. В этой книге описаны архитектурные паттерны, позволяющие создавать надежные, реально работающие приложения Angular.
Обновленное 3-е издание с Angular 17.1 выйдет 31 января 2024 года. Ознакомьтесь с ней на сайте AngularForEnterprise.com, чтобы освоить передовую разработку на Angular!