Angular 8菜单中的用户登录/注销按钮未更新

问题描述 投票:0回答:1

我有一个带有登录/注销按钮的mat-toolbar,网站的用户可以随时登录或注销。我有一个身份验证服务,该服务使用用户数据创建一个Observable并将登录按钮使用*ngIf="!(authService.user$ | async)。但是,除非我手动刷新整个页面,否则这将无法正常工作。为什么会这样?对此有何作用?我以为Observable会在这些情况下实际起作用,但是显然我缺少了一些东西。

我还尝试在app.component.ts中将Observable订阅为user,并在模板中使用user,但这似乎无济于事。我知道关于Observables用户登录有几个问题,以及有关刷新的问题,但是它们并没有使我理解为什么它不起作用。

authentication.service.ts]的相关部分:]

@Injectable({
  providedIn: 'root'
})

export class AuthenticationService {
  user$: Observable<User>;
  viewAllUser: Boolean = false;

  constructor(
    private afAuth: AngularFireAuth,
    private afs: AngularFirestore,
    private router: Router) {

    this.user$ = this.afAuth.authState.pipe(
      switchMap(user => {
        if (user) {
          return this.afs.doc<User>(`Users/${user.uid}`).valueChanges()
        } else {
          return of(null)
        }
      }))
  }

  /* Sign up */
  SignUp(email: string, password: string) {
    this.afAuth.auth.createUserWithEmailAndPassword(email, password)
      .then((result) => {
        window.alert("You have been successfully registered!");
        this.updateUserData(result.user)
        //console.log(result.user);
      }).catch((error) => {
        window.alert(error.message);
        //console.log(error.user);
      });
  }

  /* Sign in */
  SignIn(email: string, password: string) {
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((result) => {
        window.alert("You have been successfully signed in!");
        this.updateUserData(result.user);
        //console.log(result.user);
      }).catch((error) => {
        window.alert(error.message);
        //console.log(error.user);
      });
  }

  /* Sign out */
  SignOut() {
    this.router.navigate(['user-main']);
    this.afAuth.auth.signOut();
    window.alert("You have been successfully signed out!");
  }

 private updateUserData(user) {
        // Sets user data to firestore on login
        const userRef: AngularFirestoreDocument<any> = this.afs.doc(`Users/${user.uid}`);
        const data: User = {
          uid: user.uid,
          email: user.email,
          roles: {
            growth_technician: true //default role
          }
        }
        return userRef.set(data, { merge: true }) //Update in non-destructive way 
      }
}

app.component.html:

<body>
  <mat-toolbar>
    <span>
      <button mat-menu-item *ngIf="!(authService.user$ | async) as user" routerLink="/user-main">Login</button>
      <button mat-menu-item (click)="authService.SignOut()" routerLink="/user-main" *ngIf="authService.user$ | async">Logout</button>
      {{user.email}} //for testing
    </span>
    <span>
      <button mat-icon-button [matMenuTriggerFor]="appMenu">
        <mat-icon>more_vert</mat-icon>
      </button>
    </span> 
  </mat-toolbar>
  <mat-menu #appMenu="matMenu">
    <!-- Only to be shown to logged in users: -->
    <button mat-menu-item *ngIf="authService.user$ | async" routerLink="/user-main">User main</button>
    <button mat-menu-item *ngIf="authService.user$ | async" routerLink="/page_x">Page X</button>
    <button mat-menu-item *ngIf="authService.canViewData(authService.user$ | async)==true" routerLink="/secret_page_y">Secret page Y</button>
  </mat-menu>

  <!--This is where the routes are shown-->
  <router-outlet></router-outlet>
</body>

app.component.ts:

import { Component } from '@angular/core';
import { AuthenticationService } from './shared/authentication.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  user;

  constructor(public authService: AuthenticationService) {
    this.authService.user$.subscribe(user => this.user = user);
  }
}

我有一个带登录/注销按钮的mat-toolbar,网站用户可以随时登录或注销。我有一个身份验证服务,该服务使用用户数据并使用* ngIf = ...

angular authentication menu page-refresh
1个回答
0
投票

您应该为用户使用BehaviorSubject,并像这样使用它:

© www.soinside.com 2019 - 2024. All rights reserved.