Angular 6 - Как остановить бесконечный опрос в подписке () - PullRequest
0 голосов
/ 23 апреля 2019

Итак, я хочу показать значок в зависимости от того, является ли количество проектов в моем списке> 3. Я использую эту функцию getProjects (), на которую мне нужно подписаться, чтобы получить данные. Я устанавливаю логическое значение, когда я подписываюсь, чтобы проверить количество проектов в списке, а затем в своем HTML я использую ngIf, чтобы показать значок, основанный на логическом значении. Я могу заставить его отображаться правильно, однако, я думаю, что я постоянно опрашиваю свою подписку и устанавливаю это логическое значение снова и снова, потому что это заставляет мою веб-страницу работать очень медленно.

Я уже попробовал метод take (1), который, кажется, не останавливает подписку, а также установил для него область "this.variable" внутри моего компонента. В настоящее время я использую источники событий, но это тоже не работает.

Пока это мой код,

Функция, на которую я подписываюсь (в другом компоненте):

getProjects(): Observable<ProjectInterfaceWithId[]> {
    const organizationId = localStorage.getItem('organizationId');
    return this.firestoreService.collection('organizations').doc(organizationId)
      .collection('projects').snapshotChanges()
      .pipe(
        map(actions => actions.map(a => {
          const data = a.payload.doc.data() as ProjectInterface;
          const id = a.payload.doc.id;
          return {id, ...data} as ProjectInterfaceWithId;
        })),
        map(list => {
          if (list.length !== 0) {
            this.buildProjectLookup(list);
            this.projects = list;
            return list;
          }
        })
      );
  }

Функция, которую я использую для получения данных и установки логического значения:

@Input() toggle: boolean;
@Output() iconStatus = new EventEmitter();

displayIcon() {
    this.projectService.getProjects()
      .pipe(take(1))
      .subscribe(
        list => {
          if(list.length >= 3){
              this.toggle = true;
              this.iconStatus.emit(this.toggle);
          }
        });
  }

HTML:

<i *ngIf="displayIcon()" class="material-icons">list</i>

Можно ли как-нибудь буквально проверить длину списка один раз, чтобы я не попал в этот цикл подписки? Заранее спасибо!

1 Ответ

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

Похоже, что это может произойти из-за ngIf, ссылающегося на метод displayIcon().

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

см. https://blog.angular -university.io / how-do-angular-2-change-Detection-Real-Work / для более

Один из способов исправить это - вместо этого сделать ngIf ссылкой на переменную.Например, вы можете установить наблюдаемую projects$, используя

this.projects$ = this.projectService.getProjects()
      .pipe(
         take(1),
         tap(projects => this.iconStatus.emit(projects.length >= 3))
      );

Эта наблюдаемая, вероятно, должна быть реализована в вашем методе ngOnInit().Тогда в вашем шаблоне вы можете использовать

<i *ngIf="(projects$ | async)?.length >= 3" class="material-icons">list</i>

...