Ваш эффект можно проверить в хранилище ngrx и игнорировать действие, если данные уже получены. Если у вас есть какой-то срок действия данных, вы можете проверить это, а не только существующие данные.
Примерно так:
@Effect()
findSettings$ = this.actions$
.ofType(SettingsActionTypes.RetrieveSettings)
.withLatestFrom(store.select(...)) // select your state
.filter(([action, state]) => state == null) // if not initialized
.exhaustMap(([action]) => ...); // initialize state
Таким образом, вы продолжаете отправлять действие везде, где требуется состояние. Вы также можете использовать распознаватель маршрутов или что-то подобное, чтобы выполнить диспетчеризацию, а не помещать ее в свой компонент. Мне нравится делать это, когда у меня есть несколько компонентов по одному и тому же родительскому маршруту, которым требуются данные, или когда мне нужно существование нескольких частей состояния, и я не хочу повторять диспетчеризацию во многих компонентах.
В качестве альтернативы вы можете создать службу, которая имеет внутреннюю ссылку на хранилище и выставляет каждый фрагмент состояния как наблюдаемый. При доступе или подписке это обеспечит гидратацию состояния. Это, вероятно, лучший вариант, чем распространение логики вокруг вашего приложения относительно того, как гидратируется ваше состояние. Я обнаружил, что если я распространяю их, то забываю иногда инициализировать их и получаю эти странные ошибки, в которых у меня могут быть или не быть необходимые данные на странице на основе предыдущих страниц, которые я посетил.
Проблема в целом
Есть много возможных подходов к этой проблеме, и я лично не остановился на одном. Я нахожу, что подписаться на состояние и направить действие по увлажнению воды - это все равно, что отдать мой заказ на ужин официанту, а затем рассказать кухне, какие ингредиенты купить в магазине. Это создает концептуальную тесную связь, где я как потребитель должен знать, как составляется то, что я потребляю. В идеальном мире простое действие подписки (выдача моего заказа) сообщит производителю (-ям), что им нужно сделать без дальнейших инструкций со стороны потребителя / подписчика.
В ngrx производители, похоже, отсоединены от потребителя по замыслу. Похоже на сообщение автобуса. Это имеет смысл в свете поддержки нескольких действующих лиц (api, client, ...), влияющих на один и тот же кусок состояния. Если у вас есть только один удаленный субъект (api) в качестве продюсера, то, возможно, имеет смысл просто кэшировать данные в вашем api (shareReplay(1)
).