Угловой сервис, который возвращает наблюдаемые объекты / субъекты из массива кэша нескольким экземплярам компонента в реальном времени - PullRequest
2 голосов
/ 03 июня 2019

ИСПОЛЬЗОВАНИЕ CASE

imageUserActionsComponents each">

У меня есть страница с несколькими экземплярами UserActionsComponent.У меня также есть глобальный DataService, который выступает в качестве поставщика данных с расширенным кэшированием (wannabe).

Иерархия выборки данных:

Кэш в памяти >> Хранение в браузере (асинхронное)>> HTTP-запрос

UserActionsComponent

Запросы dataService.getData(URL,params,method)

PS: params содержит такие детали, как blogId, что делает уникальной хэш-подпись

DataService (.getData ())

1) Создает уникальный хеш-ключ, используя что-то вроде genUniqueHash (URL + stringify (params) + метод)

2) Проверяет, присутствует ли значение в кеше в памяти (массив [KEY]) - Если да, возвращает ob $

3) Проверяет, присутствует ли значение в хранилище браузера (асинхронно; использует хранилище Ionic) - Если да, вернуть ob $ else - сохранить в кэш в памяти, затем вернуть ob $ (массив [KEY])

4) Получить значение из HTTP Call, сохранить в хранилище, сохранить вкеш памяти и возврат ob $ (array [KEY])

Эта концепция не работает, так как я не могу понять, как вернуть общийнаблюдаемый (я предполагаю, что это должен быть BehaviourSubject?) из массива значений кэша.Пожалуйста, приведите меня на правильный путь.

ПРИМЕЧАНИЯ

  • Если пользователь голосует в одном компоненте, он должен отражать все остальные экземпляры в поле зрения (все UserActionsComponent этой конкретной записи блога должны обновляться)
  • Может быть много UserActionsComponent в одном представлении (например, для BlogEntry # 1 и BlogEntry # 25) на одной странице!
  • Кэш в памяти продолжает расти, когда пользователь посещает новыеСообщения блога (это нормально, так как это ограниченный набор)

Я новичок в RxJS.Я попытал счастья с:

  • pipe (share ()) [Так как это служба, канал был разделен со всеми URL-адресами]
  • возвращение (cache [key]) [Не сработало, так как действия пользователя последнего извлеченного BlogEntry отразились бы на всех подписках]
  • , возвращая весь кеш и затем отфильтровывая необходимые данные (используя массив [KEY]) в конце UserActionsComponent (Этотекущая реализация)

Текущая реализация работает, но это не лучший способ сделать это для этого варианта использования.Причина: в одном представлении может быть до 20 UAC [UAC-A (1), UAC-B (1), UAC (200) ...].UAC отправляет next () дважды.onInit UAC и когда пользователь голосует "за" или "против" в UAC.Теперь, поскольку при изменении мы генерируем данные кэша, массив размером 20 генерируется 2 * 20 раз для этого просмотра страницы.

Каков был бы наиболее оптимизированный способ реализовать это с помощью RxJS?

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

Текущая реализация:

Запишите это, так как это будет полезно для кого-то в будущем.Мне удалось оптимизировать его, используя наблюдаемый шаблон следующим образом:

  • UAC onInit () вызывает dataService.getData(url,params,method,guid)
  • guid, переданный UAC, является ключом кеша для службы
  • UAC имеет две подписки от dataService.Одним из них является метод dataService.getData, который возвращает наблюдаемое - в основном используется как инициализатор для установки guid - он отписывается после получения своего первого значения с помощью .pipe(first()).Вторая подписка на объект BehaviourSubject с именем dataChanged.Всякий раз, когда данные изменяются в кэше dataService, они выдают dataChanged.next(newDataDelta).Эта подписка сохраняется до тех пор, пока компонент onDestroy.
  • dataService иерархически проверяет как cache[guid] > storage[guid] > http[url], соответственно устанавливает данные и, наконец, вызывает dataChangedSubj.next(cache[guid]) . Будет отправлена ​​только измененная дельта
  • Все UAC получают новый кэшированный DataSet (который является кешем [guid]; содержит только то, что было изменено) и проверяет receivedData[guid], чтобы определить, относятся ли отправленные данные к UAC.Если да, он потребляет его.
  • Если пользователь голосует "за" / "против" на UAC, UAC выполняет необходимые вызовы API, а в случае успеха выполняет dataService.updateData (guid, data), которая, в свою очередь,выдает изменение, используя dataChanged.next(newDataDelta) для всех UAC, и UAC, принадлежащие одному и тому же сообщению в блоге, обновляют свои данные (поскольку они будут иметь одинаковый guid)

Все еще открыты для лучшего способа реализацииэтот вариант использования с использованием RxJS.

0 голосов
/ 03 июня 2019

Вы можете использовать только одну тему / поведение субъекта. Возвратите это как наблюдаемое, на которое каждый UAC может подписаться и прослушать данные. Теперь я предполагаю, что к каждому UAC должен быть привязан уникальный идентификатор, скажем, идентификатор блога. Поэтому, когда вы отправляете данные, используя Subject, вместе с данными, добавьте этот идентификатор блога в эти данные. В случае совпадения с UAC, если идентификатор UAC совпадает с идентификатором, полученным из наблюдаемого, обновите данные в UAC, иначе игнорируйте. Таким образом, правильный UAC будет обновлен. Например: -

data.service.ts

const a = new BehaviourSubject();

getDataSource() {
 return a.asObservable():
}

cacheCheck(blogId: string) {
  // emit the data with a blogId.
  a.next({'id': blogId, 'data': getDataFromSomeWhere()})
}

blog.component.html

<app-uac [id]="blogId"></app-uac>

uac.component.ts

@Input id: string;
constructor(public dataService: DataService) {}
ngOnInit() {
   dataService.getDataSource().subscribe((data) => {
      if(data.id == this.id) //do somethin in UAC or emit event to parent
         //blog and let it do something
      else { //ignore}
   })
}

Что-то в этой строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...