Два разных наблюдаемых в одной и той же коллекции Firestore вызывают утечку памяти и показывают повторяющиеся результаты - PullRequest
0 голосов
/ 24 апреля 2019

Я использую @ angular / fire для извлечения данных из магазина.У меня есть два компонента.один - родитель, а другой - ребенок.Оба эти компонента подписываются на наблюдаемые с помощью асинхронных каналов.Это две разные наблюдаемые (но в одной коллекции).Когда я прибываю на дочерний маршрут, я вижу данные из родительского маршрута, пока наблюдаемый дочерний компонент не даст ответ и не заменит данные, которых там быть не должно.Почему это происходит?

Это метод, который возвращает наблюдаемую, которая используется родительским компонентом.

getMyTasks(workspaceID, userID) {
return this.afs.collection('Tasks', ref => ref.where(`workspaceID`, '==', workspaceID).where(`members.${userID}`, '==', true))
  .snapshotChanges().pipe(
    map(actions => actions.map(a => {
      const data = a.payload.doc.data() as Task;
      const id = a.payload.doc.id;
      let member = data.members;
      let isMember = false;
      for (var b in Object.keys(data.members)) {
        if (Object.keys(member)[b] === userID) {
          isMember = true;
          break;
        } else {
          isMember = false;
        }
      }

      let createdBy = data.createdBy;
      let creatorName = "";

      for (let i = 0; i < this.members.length; i++) {
        if (this.members[i].memberId === createdBy) {
          creatorName = this.members[i].data.name;
        }
      }
      return { id, creatorName, isMember, ...data };
    }))
  );

}

this.tasks$ = this.firestoreService.getMyTasks(this.workspaceID, this.userID);

А затем я использую асинхронный канал вшаблон.А вот метод, который используется в дочернем компоненте

getTasks(projectId, members) {
return this.afs.collection('Tasks', ref => ref.where('projectId', '==', projectId).orderBy("createdAt", "desc"))
  .snapshotChanges().pipe(map(actions => actions.map(a => {
    const data = a.payload.doc.data() as Task;
    const docId = a.payload.doc.id;
    let createdBy = data.createdBy;
    let creatorName = "";

    for (let i = 0; i < members.length; i++) {
      if (members[i].memberId === createdBy) {
        creatorName = members[i].data.name;
      }
    }

    return { docId, ...data, creatorName }
  })))}

, это дочерний компонент.ts

this.tasks = this.firestoreService.getTasks(this.projectId, this.members);

1 Ответ

0 голосов
/ 24 апреля 2019

Кажется, CollectionReference - это объект, который существует только один раз для каждой коллекции.

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

Родитель и дочерний элемент слушают оба запроса на один и тот же результат, следовательно, повторяющиеся результаты.

Я вижу три решения этой проблемы.

  1. Родитель должен просто получить данные один раз, и ребенок сможет прослушать изменения данных.

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

  3. Если вам не требуется обновлять данные об изменениях, вы можете просто получить все данные один раз.

Я зависит от того, чего вы пытаетесь достичь.

Редактировать:

Если все документы имеют одинаковую структуру.

Вы можете запросить все необходимые документы.Может быть, все документы, к которым пользователь может получить доступ.

Тогда вы можете создать сервис, который подписывается на наблюдаемый запрос.Теперь вам нужно обработать документы, отфильтровать или что-то еще.И создайте две новые наблюдаемые, которые испускают ваши отфильтрованные документы.

Каждый раз, когда наблюдаемая информация запрашивает обновление, вы можете испускать вновь обновленные данные с вашими наблюдаемыми.

Thisто, как вы можете просто использовать асинхронный канал в своих наблюдаемых объектах.

Это, возможно, лучшее решение, если есть связь между вашим родителем и ребенком Tasks.

...