Angular 6-如何在subscribe()中停止无限轮询

时间:2019-04-23 03:09:24

标签: html angular event-handling parent-child infinite-loop

因此,我想根据列表中的项目数是否大于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 :(得分:0)

由于ngIf引用了displayIcon()方法,因此似乎正在发生。

每次在组件中运行更改检测时,都会调用此方法。如果您的组件使用默认更改检测,那么这种情况将很常见。

有关更多信息,请参见https://blog.angular-university.io/how-does-angular-2-change-detection-really-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>