Предположим есть приложение написанное на компонентах (angular.component). Там к примеру несколько стэйтов, показывающих транзакции, категории и аккаунты, и есть сайдебар в котором висит общий виджет, отображающий состояние аккаунтов.
виджет это компонент, и берет данные из своего сервиса, который в свою очередь использует $http.
Так вот, при создании изменении или изменении транзакции, или аккаунта, инфо в этом виджете надо обновлять с сервера.
Конечно можно накопипастить 6 раз к каждому из требуемых запросов, обновление и виджета следом, в стиле:
TransactionService.update(this.transaction).then(() => SidebarService.refreshStats());
Но вдруг появятся еще виджеты? либо другие стэйты и условия для обновления, хочется найти какое нибудь более правильное решение.
Пробовал реализовывать это через $http интерсепторы, чтобы по каждому апдейту, на определнном URL, шло это обновление, но туда не удавалось заинжектить сервис этого виджета, так как получалась ошибка Circular dependency, $http провайдера.
Какие есть еще решения, для обновления данных, для каких то зависящих друг от друга компонента?
Какие есть еще решения, для обновления данных, для каких то зависящих друг от друга компонента?
Пожалуй наиболее удобный способ (но не сказать что самый простой, просто наиболее гибкий) это запретить компонентам получать стэйт самостоятельно и прокидывать его через биндинги снаружи. А снаружи получать стэйт через ресолверы роутера. Соответственно когда вы меняете стэйт в каком-то компоненте, вы просите это сделать сервис, а сервис уже как-то уведомляет систему о изменении стэйта и перезагружаются нужные ресолверы.
Таким образом состояние будет ходить по кругу, что сильно упрощает тестирование и проектирование приложения, компоненты становятся полностью независимыми и отвечают только за презентационную логику...
Сейчас резолвы из роутера я использую для каких то более важных компонентов/данных, без которых функционирование не возможно в принципе, таких как, данные о юзере ,при авторизации и так далее. А не особо важные данные, компоненты грузят самостоятельно из сервиса по ходу дела, чтобы не ожидать лишнее время резолва и держать максимально логику в себе, оставаясь самостоятельными единицами. Из роутера обычно прокидываю только параметры стэйта/url, такие как id и так далее.
Просто этот виджет он основной, так сказать системный, висит на сайдбаре, т.е на родительском уровне, тех подстейтов которые уже меняются юзером. Сам он грузится и резолвится один раз всего, при загрузке приложения.
"а сервис уже как-то уведомляет систему о изменении стэйта и перезагружаются нужные ресолверы." - вот так наверное лучше было бы мне вопрос сформулировать, как именно стоит делать эти уведомления между сервисами?
Я пока вижу два пути:
1) делать флаг на подобии isChanged, который обновляется при методах patch, post, detele и повесить на него вотчер из соседнего сервиса, который грузит данные при его изменении, но это опять же не сэкономит строк по сравнению с тем что есть сейчас:
TransactionService.update(this.transaction).then(() => SidebarService.refreshStats());
будет:
TransactionService.update(this.transaction).then(() => this.isChanged = true);
+ дополнительный вотчер и флаг в каждом сервисе.
2) Второй использовать эвенты и подписываться на них
Круче всего, как мне кажется конечно, было бы реализовать идею с интерсептором, который при определенном url и методе, дергает обновление данных в сервисе, тогда с дальнейшим расширением, не было бы вообще проблем.
> идею с интерсептором, который при определенном url и методе, дергает обновление данных в сервисе,
зачем если можно явно в сервисе затригирить ивент? Или явно дернуть метод. Или декорацию/композицию использовать... много всего можно сделать и я не могу вам сказать какой способ лучше. В любом случае это уже не касается angular-а особо.