Как хранить и обрабатывать данные с помощью angular, ngrx и redux, когда некоторые компоненты запрашивают одни и те же данные с сервера?

#angular #redux #ngrx

#angular #redux #ngrx

Вопрос:

Я использую Angular7 с ngrx в своем проекте, и мне нужно извлекать и сохранять данные для нескольких одинаковых компонентов. Например:

  1. У меня есть две (многие ко многим) модели Author и Book

  2. У меня есть AuthorListComponent, который показывает некоторый список AuthorCardComponent.

  3. AuthorCardComponent содержит кнопку «Показать лучшие книги».

  4. Когда пользователь нажимает на эту кнопку, AuthorCardComponent должен получать с сервера лучшие книги, написанные автором.

Насколько я понимаю redux, мне нужно нормализовать данные, т.е.

  1. Храните все загруженные книги в одном месте (кэш книг)

  2. Сохраняйте все пары запрос-ответ со ссылками на кеш книг

  3. Сохраняйте, сколько ответов содержит каждая книга, чтобы очистить кэш книг от неиспользуемых книг.

  4. Все выборки дублированных книг с сервера должны сравниваться с сохраненными экземплярами и перезаписываться, если некоторые свойства отличаются.

Итак, хранилище выглядит так

 store = {
    authors: {/* .... */},
    books: {
        totalRequests: 3,
        requests: {
            "request1": {
                request: {authorId: 77},
                status: 'done',
                total: 3,
                bookIds: ['15', '99', '101']
            },
            "request2": {
                request: {authorId: 88},
                status: 'loading',
            },
            "request3": {
                request: {authorId: 66},
                status: 'done',
                total: 5,
                bookIds: ['55', '94', '141']
            }
        },
        booksCache: {
            '15': { id: '15', label: '...', /* .... */ },
            '55': { id: '55', label: '...', /* .... */ },
            '94': { id: '94', label: '...', /* .... */ },
            /* ... */
        }
    }         
}
  

Не так сложно написать все эти создатели действий, редукторы, эффекты размера и так далее, Но у меня есть несколько нерешенных вопросов:

  1. Как AuthorCardComponent может получить правильный селектор для получения статуса запроса и данных ответа? Когда AuthorCardComponent вызывает
 this.store.dispatch({action: 'BOOKS_GET', payload: {request: {authorId: id}});
  

он не знает, как подписаться на собственный ответ, если этот номер ответа генерируется reducer.

  1. Как AuthorCardComponent может сообщить хранилищу, что последний запрос больше не нужен?

  2. Есть ли более простой способ решить проблему с раздельным хранением книг и ответов?

  3. Есть ли более подходящий диспетчер состояний вместо ngrx / redux?

Комментарии:

1. Почему запрос / сохранение одних и тех же данных является проблемой?

2. @DanNguyen Когда несколько компонентов authorcard отправляют запросы независимо, каждый из них должен получать только собственный ответ. Я могу хранить запросы как хранилище ключ-значение, но как AuthorCardComponent узнает, какой ключ использовать?

Ответ №1:

Вы захотите использовать созданный вами селектор для получения информации из состояния. Это было бы что-то вроде этого:

   books$: Observable<BooksStateDetails> = this.store.pipe(
    select(selectBooks)
  );
  

Вы можете использовать что-то подобное выше в каждом компоненте, которому нужны данные, просто выберите его из хранилища. Затем вы можете использовать async канал для отображения данных по мере необходимости.

async Канал автоматически откажется от подписки.

Комментарии:

1. В этом случае AuthorCardComponent получает состояние всех книг. Он должен получать только собственные данные запроса, но не знает собственного номера запроса. Я добавил структуру хранилища, чтобы сделать мой вопрос более понятным.

2. похоже, вам нужен AuthorCardDetailComponent, который отображает выбранную книгу, которая запускается с помощью этой кнопки в родительском компоненте.

3. Каждый AuthorCardComponent содержит собственную кнопку и получает собственный список книг и отображает его на собственной расширенной панели.

4. Я действительно не слежу, не видя больше кода — можете ли вы поместить репозиторий в stackblitz или что-то подобное?

5. Не могли бы вы или вы сохранить список запросов в состоянии авторов? Скажем, что-то подобное requests: ['request1', 'request2'] , что вы могли бы использовать, чтобы указать в книгах, какие запросы больше не нужны?