У меня такая структура:
состояние:
@Selector()
static getClientById(state: ClientListStateModel) {
return (id: number) => state.clientList.find(f => f.id === id);
}
фасад (storeService):
@Select(ClientListState.getClients) clients$: Observable<ClientModel[]>;
@Dispatch()
getClientList() {
return new GetClientList();
}
компонент:
this.storeService.getClientById(clientId).subscribe(result => this.client = result)
Идея состоит в том, что на главной странице (clientList) я отправляю действие, которое загружает всех клиентов,
this.storeService.getClientList();
, а затем на странице сведений, я хочу иметь возможность динамически выбирать клиента по идентификатору из activeRoute и отображение всех данных о клиенте (без нового вызова серверной части, просто выбирая часть состояния).
Если бы не фасад (storeService), я мог бы вставить @Select прямо в компонент и использовать динамический c clientId, например, например:
@Select(ClientListState.getClientById(this.clientId)) client$: Observable<ClientModel>;
private clientId;
ngOnInit() {
this.clientId = this.route.get('id')
}
Я не могу использовать то же самое подход в фасаде (storeService), поскольку у меня нет ссылки на clientId, и очень грязно каким-то образом вводить его туда.
То, что я придумал, - это чтение документации и использование селектора Dynami c (https://www.ngxs.io/concepts/select):
фасад (storeService):
@Select(ClientListState.getClients) clients$: Observable<ClientModel[]>;
constructor(private store: Store) {
}
getClientById(id): Observable<ClientModel> {
return this.store.select(ClientListState.getClientById(id));
}
@Dispatch()
getClientList() {
return new GetClientList();
}
состояние:
// DynamicSelector
static getClientById(id: keyof ClientListStateModel) {
return createSelector([ClientListState], (state) => {
return state.clientList.find(c => c.id === id);
});
}
и, наконец, в компоненте
this.storeService.getClientById(this.clientId);
Пока это работает, почему-то я не совсем уверен, что это самое чистое решение.
Прежде всего, мне не нравится, что в фасаде я вынужден вводить хранилище (поскольку это одна из основных причин, по которой декораторы @SelectSnapshot и @Dispatch были добавлены в ngxs-labs) для исключения хранилища из конструктора.
Я действительно много искал, но не смог find ... Есть ли у нас возможность создать динамический c Selector, каким-то образом внедрив функцию, например: @Select ((id) => SomeState.getSomeDataById (id)) и каким-то образом передав Id через @Selector?
Это скорее открытый вопрос / обсуждение. Я считаю, что есть люди, которые задают те же вопросы. Спасибо!