Angular 中的 Meteor User Observable 未按预期做出反应

Meteor User Observable in Angular not reacting as expected

我目前通过 meteor-rxjs 包将 Meteor 与 Ionic 一起使用。最近我为登录工具栏制作了一个组件。如果我已登录,它应该会显示我的用户名和头像,如果我当前未登录,它应该会显示一个登录按钮。

该组件与存储包含用户信息的 user$ Observable 的帐户服务相关联,因此只要我的登录状态发生变化,它就会做出反应。

虽然没有按预期做出反应。如果我注销并尝试登录,视图不会改变。但是,如果我在登录时重新加载页面,我可以注销并登录,并且视图始终对我的状态变化做出反应。

账户服务:

export class AccountService {

  user$: Observable<Meteor.User>;

  constructor() {

    this.user$ = Users.find({_id: Meteor.userId()}).pipe(zoneOperator());

  }
}

注意:zoneOperator() 是 meteor-rxjs 的一个函数,每次新数据到达 Mongo 游标可观察时都会调用 ngZone。

组件

  <ion-toolbar>
    <ion-buttons *ngIf="(account.user$ | async) as users" slot="end">

      <ion-item *ngIf="users.length > 0 ; else loginTP">
        <ion-avatar class="ion-margin-end">
          <img src="{{users[0].avatar}}">
        </ion-avatar>
        <ion-label>{{users[0].username}}</ion-label>

        <ion-button (click)="logout()">
          <ion-icon name="log-out-outline"></ion-icon>
        </ion-button>
      </ion-item>

      <ng-template #loginTP>
        <ion-button (click)="login()">
          <ion-icon slot="start" name="log-in-outline"></ion-icon>
          Login
        </ion-button>
      </ng-template>

    </ion-buttons>
  </ion-toolbar>

问题是如果我最初没有登录,视图不会更新。它仅在我一开始登录时才按预期工作。我的假设是初始状态不知何故不是反应性的。

如果我未登录,

Meteor.userId() 为 null。

但是在 AccountService 中记录 this.user$ 表明 Users.find({_id: null}) 仍然是 returns 一个 Observable。

如有任何帮助,我们将不胜感激。 :)

我找到了一个使用内置依赖跟踪系统的 Meteors 的解决方案:Tracker即使我最初注销,这也会正确更新视图。这是最终代码:

服务

export class AccountService {

  user$: Observable<Meteor.User>;

  constructor() {
    const ctrl = this;

    Tracker.autorun(() => {
      Users.find({_id: Meteor.userId()})
          .pipe(take(1), zoneOperator())
          .subscribe(user => {
        if (user) {
          ctrl.user$ = user[0];
        } else {
          ctrl.user$ = EMPTY;
        }
      });
    });
  }

}

组件

  <ion-toolbar>
    <ion-buttons slot="end">
      <ion-item *ngIf="account.user$ as user ; else loginTP">
        <ion-avatar class="ion-margin-end">
          <img src="{{user.avatar}}">
        </ion-avatar>
        <ion-label>{{user.username}}</ion-label>

        <ion-button (click)="logout()">
          <ion-icon name="log-out-outline"></ion-icon>
        </ion-button>
      </ion-item>

      <ng-template #loginTP>
        <ion-button (click)="login()">
          <ion-icon slot="start" name="log-in-outline"></ion-icon>
          Login
        </ion-button>
      </ng-template>

    </ion-buttons>
  </ion-toolbar>