首页 > 解决方案 > Material 2 对话框中的 Angular 5 主题

问题描述

在材料 2 对话框中实现移动版导航的身份验证时遇到了这个奇怪的错误。

我编写了一个身份验证服务,负责验证用户令牌并将结果存储在主题中:

  userSignedIn$: Subject<boolean> = new Subject();

  constructor(public authService: Angular2TokenService) {

    this.authService.validateToken().subscribe(
      res => res.status == 200 ? this.userSignedIn$.next(res.json().success) : this.userSignedIn$.next(false)
    )
  }

接下来,我有一个将移动导航作为材料 2 对话框启动的功能(它是移动导航的一个完全独立的组件):

 //the event listener is used to trigger the login/signup dialog and shouldn't be the problem here
 presentMobileMenuDialog(): void {
    let dialogRef = this.dialog.open(MobileMenuComponent, {
      height: '100%',
      width: '100%',
      maxWidth: '100vw',
      panelClass: 'deine-mutter'
    });

    const sub = dialogRef.componentInstance.onClick.subscribe(action => {
      this.presentAuthDialog(action)
    });
  }

接下来是我的移动菜单组件,这里没什么特别的:

export class MobileMenuComponent implements OnInit {
  onClick = new EventEmitter<string>();
  constructor(
    public dialogRef: MatDialogRef<MobileMenuComponent>,
    //initializing the authService which will be used in the html template
    public authService: AuthService,
    private router: Router,
  ) { }

  ngOnInit() {
  }

  closeMenu(){
    this.dialogRef.close()
  }

  //for triggering login and signup dialog (not part of the problem, but I left it just in case im missing something)
  presentAuthDialog(mode) {
    this.closeMenu()
    this.onClick.emit(mode)
  }

  //basic routing and closing the dialog
  forward(link){
    this.closeMenu();
    this.router.navigate([link]);
  }


  logout() {
    this.closeMenu()
    this.authService.logOutUser().subscribe(() => this.router.navigate(['/']));
  }

我们转到 html 模板,这就是问题所在:

<div class="mobile-menu fluid-container">
  <div class="row">
    <div class="col-12 close">
      <mat-icon (click)="closeMenu()">close</mat-icon>
    </div>
    <div class="col-12 search">
      <app-search></app-search>
    </div>
    <div class="col-12 menu-items">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item">
          <a class="nav-link" id="coins" (click)="forward('/coins')">Coins</a>
        </li>
        <li class="nav-item">
          <a class="nav-link"(click)="forward('/global')">Global Stats</a>
        </li>
        <li *ngIf="(authService.userSignedIn$ | async)" class="nav-item">
          <a class="nav-link" id="profile" (click)="forward('/profile')">Profile</a>
        </li>
        <li *ngIf="(authService.userSignedIn$ | async)" class="nav-item">
          <a (click)="logout()" class="nav-link">Logout</a>
        </li>
        <li *ngIf="!(authService.userSignedIn$ | async)" class="nav-item">
          <a class="nav-link" (click)="presentAuthDialog('login')" >Login</a>
        </li>
        <li *ngIf="!(authService.userSignedIn$ | async)" class="nav-item">
          <a class="nav-link" (click)="presentAuthDialog('register')">Register</a>
        </li>
      </ul>
    </div>
  </div>
</div>

所以我遇到的问题是,无论我是否登录,菜单都会显示登录和注册。让我感到困惑的是,我在桌面版导航中使用了相同的 authService 和 ngIf 参数,并且它按预期工作,唯一的区别是它没有在材料 2 对话框中实现。我玩了很长一段时间,并尝试了以下内容并始终打印预期的布尔值,但是前端模板(更改为 *ngIf="userLogedIn")不会做出预期的更改。

//shortend the class because this is getting way to long already
userLogedin: boolean = false;
  ngOnInit() {
    this.checkAuthStatus();
  }

  presentAuthDialog(mode) {
    this.dialogRef.close()
    this.onClick.emit(mode)
    this.checkAuthStatus()
  }

  logout() {
    this.dialogRef.close()
    this.authService.logOutUser().subscribe(() => this.router.navigate(['/']));
    this.checkAuthStatus();
  }

  checkAuthStatus(){
    this.authService.userSignedIn$.subscribe(data => {
      this.userLogedin = data;
      console.log(data)
    })
  } 

所以我很困惑为什么会发生这种情况,很抱歉这已经变得如此之久。

标签: angulartypescriptangular-material2

解决方案


因此,当在 authService 中使用 BehaviorSubject 时,一切都按预期工作。再次阅读文档,使用 BehaviorSubject 确实更有意义。我仍然不确定,为什么它对其他导航有效。

更新服务:

 userSignedIn$ = new BehaviorSubject<boolean>(false);

  constructor(public authService: Angular2TokenService, private http: Http) {

    this.authService.validateToken().subscribe(
      res => res.status == 200 ? this.userSignedIn$.next(res.json().success) : this.userSignedIn$.next(false)
    )
  }

推荐阅读