AngularFire auth, шаблон не обновляется при изменении Observable <User> - PullRequest
0 голосов
/ 02 февраля 2020

Я обычный пользователь Angular, поэтому, возможно, я упускаю что-то очевидное.

Я проследил этот урок из fireship.io, чтобы интегрировать аутентификацию в мое приложение angular using angularfire.

После входа в систему наблюдаемый AuthService.user $ изменится, но шаблон не обновится в компоненте UserProfile.

Использование приведенного ниже фрагмента кода подтверждает наличие данных. .

<code><pre>{{auth.user$ | async | json}}

Похоже, это как-то связано с обновлением наблюдаемой за пределами ngzone. Я попытался вручную обнаружить изменения, внедрив ChangeDetectorRef в компонент и вызвав deteChange из обратного вызова подписки AuthService.user $, но безуспешно.

Мне удалось заставить его работать, как и ожидалось, путем изменения профиля пользователя. component.ts к следующему:

@Component({
  selector: 'app-user-profile',
  templateUrl: './user-profile.component.html',
  styleUrls: ['./user-profile.component.css']
})
export class UserProfileComponent implements OnInit {

  userData?: User;

  constructor(public auth: AuthService) {
    this.auth.user$.subscribe(d => this.userData = d)
  }
}

И user-profile.component. html к следующему:

<div *ngIf="userData; then authenticated else guest">
</div>

<ng-template #guest>
  <h3>Hello</h3>
  <p>Login to get started...</p>

  <button (click)="auth.googleLogin()">
    <i class="fa fa-google"></i> Connect Google
  </button>
</ng-template>

<ng-template #authenticated>
  <div *ngIf="userData as user">
    <h3>Hello, {{ user.displayName }}</h3>
    <img [src]="user.photoURL">
    <button (click)="auth.signOut()">Logout</button>
  </div>
</ng-template>

Вот мои зависимости, извлеченные из пакета. json.

{
  "@angular/animations": "~8.2.14",
  "@angular/common": "~8.2.14",
  "@angular/compiler": "~8.2.14",
  "@angular/core": "~8.2.14",
  "@angular/fire": "^5.4.0",
  "@angular/forms": "~8.2.14",
  "@angular/platform-browser": "~8.2.14",
  "@angular/platform-browser-dynamic": "~8.2.14",
  "@angular/router": "~8.2.14",
  "firebase": "^7.8.0",
  "rxjs": "~6.4.0",
  "tslib": "^1.10.0",
  "zone.js": "~0.9.1"
}

Есть идеи о том, чего мне не хватает?

1 Ответ

2 голосов
/ 03 февраля 2020

Если я не ошибаюсь, вы немного меняете код примера Джеффа Делани .

Вы используете две ng-template, а также две подписки async в вашей AuthService.user$, (одну в контейнере div, а также одну в ng-template, называемую authenticated. И это является причиной вашей проблемы.

С этим кодом ниже, он будет работать гладко:

<div *ngIf="auth.user$ | async as user; else guest">
  <h3>Hello, {{ user.displayName }}</h3>
  <img [src]="user.photoURL">
  <button (click)="auth.signOut()">Logout</button>
</div>

<ng-template #guest>
   ...
</ng-template>

Если вы хотите сохранить свой исходный код, вы можете рассмотреть возможность добавления оператора shareReplay в ваша AuthService.user$ наблюдаемая. В этом случае последнее значение Observable всегда будет доступно для новой подписки.

this.user$ = this.afAuth.authState.pipe(
  switchMap(user => {
    if (user) {
      return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
    } else {
      return of(null);
    }
  }),
  shareReplay(1)
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...