Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ngIf不';t评估异步代码和Firebase_Javascript_Angular_Firebase_Firebase Authentication - Fatal编程技术网

Javascript ngIf不';t评估异步代码和Firebase

Javascript ngIf不';t评估异步代码和Firebase,javascript,angular,firebase,firebase-authentication,Javascript,Angular,Firebase,Firebase Authentication,我的AuthService中有一个属性,它告诉您是否登录 export class AuthService { token: string; isLogIn = new Subject<boolean>(); 在我的HeaderComponent中,我有: export class HeaderComponent implements OnInit { isActivated = false; constructor(private authService: Aut

我的AuthService中有一个属性,它告诉您是否登录

export class AuthService {
  token: string;
  isLogIn = new Subject<boolean>();
在我的HeaderComponent中,我有:

export class HeaderComponent implements OnInit {
  isActivated = false;
  constructor(private authService: AuthService) { }
  ngOnInit() {
    this.authService.isLogIn.asObservable().subscribe(
      (data: boolean) => {
        this.isActivated = data;
      }
    );
    // this.isActivated = this.authService.isLogin();
  }

}
模板:

<ng-template [ngIf]="!isActivated">
      <a class="nav-item nav-link text-white anchor-hover"

         routerLink="/login"
         routerLinkActive="active font-weight-bold">
        <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
      </a>
    </ng-template>
    <ng-template [ngIf]="isActivated">
      <!--DROPDOWN PROFILE-->
      <div class="btn-group" role="group" *ngIf="authService.user">
        <button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
          {{authService.user.displayName}}
        </button>
        <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
          <a class="dropdown-item" href="#">Dropdown link</a>
          <a class="dropdown-item" href="#">Dropdown link</a>
        </div>
      </div>
      <a class="nav-item nav-link text-white anchor-hover"
         routerLink="/dashboard"
         routerLinkActive="active font-weight-bold">
        <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
      </a>
    </ng-template>
AppComponent.ts

import {Component, OnInit} from '@angular/core';
import * as firebase from 'firebase';
import {AuthService} from './public/services/auth.service';
import {User} from "./auth/models/user.model";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  isLoading = true;
  constructor(private authService: AuthService) {}

  ngOnInit() {

    // this.authService.isLogIn.next(localStorage.length > 0);

    firebase.auth().onIdTokenChanged(
      (data) => {
        console.log('TOKEN HAS CHANGED', data);
        if(data) {
          data.getIdToken().then(
            (tk) => {
              this.authService.token = tk;
            }
          );
        } else {
          console.log('You don\'t have a token yet, please login...');
          // TODO this means that the user is new or have logout.
        }
      }
    );

    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        // User is signed in.
        this.authService.user = new User(user.displayName, user.email, user.photoURL, user.uid);

        console.log(user);
        this.isLoading = false;
        this.authService.isLogIn.next(true);
      } else {
        // No user is signed in.
        console.error('no user is login');
        this.authService.isLogIn.next(false);
      }
    });

    // check localstorage, so we can see if there is a logged user
    if (this.authService.getLocalUserInfo()) {
      this.authService.isLogIn.next(true);
    } else {
      this.authService.isLogIn.next(false);
    }
  }
}
AppComponent模板:

<div>
  <app-header></app-header>
</div>


<div>
  <router-outlet></router-outlet>
</div>
AppHeader模板

<nav class="navbar navbar-expand-lg navbar-dark bg-custom-nav px-5">
  <a class="navbar-brand" routerLink="/">MovieApp</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="container-fluid">
    <div class="collapse navbar-collapse d-lg-flex justify-content-lg-between row" id="navbarNavAltMarkup">
      <div class="navbar-nav px-sm-4 px-lg-0">
        <a class="nav-item nav-link text-white"
           routerLink="/"
           routerLinkActive="active font-weight-bold"
           [routerLinkActiveOptions]="{exact: true}">Inicio</a>
      </div>
      <div class="col-lg-8">
        <app-search-bar></app-search-bar>
      </div>
      <div class="row">
        <ng-template [ngIf]="!isActivated">
          <a class="nav-item nav-link text-white anchor-hover"

             routerLink="/login"
             routerLinkActive="active font-weight-bold">
            <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
          </a>
        </ng-template>
        <ng-template [ngIf]="isActivated">
          <!--DROPDOWN PROFILE-->
          <div class="btn-group" role="group" *ngIf="authService.user">
            <button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
              {{authService.user.displayName}}
            </button>
            <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
              <a class="dropdown-item" href="#">Dropdown link</a>
              <a class="dropdown-item" href="#">Dropdown link</a>
            </div>
          </div>
          <a class="nav-item nav-link text-white anchor-hover"
             routerLink="/dashboard"
             routerLinkActive="active font-weight-bold">
            <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
          </a>
        </ng-template>

      </div>
    </div>
  </div>
</nav>


还有一件事,我使用了异步管道,但模板没有反映这些变化。在github项目中,您会发现我在模板中使用了async,但仍然存在相同的错误。我希望有人能帮助我。

我将尝试帮助/回答,请注意,有很多代码需要筛选,因此我可能遗漏了一些明显的内容。无论如何,为了整理代码并为您指明正确的方向,您可能需要查看AsyncPipe

我想首先修改您的AuthService,通过改变
isLogIn=newsubject()
to
private\u isLogIn=new Subject()。我们不想将主题共享给其他将修改它的组件,因此在AuthService中的任何地方,您都只需要添加下划线。。。最后,要导出要使用的主题,我们可以添加如下get函数:

get isLogIn(): Observable<boolean> {
   return this._isLogIn.asObservable();
}
export class HeaderComponent implements OnInit {
  constructor(private authService: AuthService) { }

  ngOnInit() {}

  get isActivated(): Observable<boolean> {
    return this.authService.isLogIn;
  }
}
现在,如果我要编写您的
header.component.ts
,我会这样做:

get isLogIn(): Observable<boolean> {
   return this._isLogIn.asObservable();
}
export class HeaderComponent implements OnInit {
  constructor(private authService: AuthService) { }

  ngOnInit() {}

  get isActivated(): Observable<boolean> {
    return this.authService.isLogIn;
  }
}
导出类HeaderComponent实现OnInit{
构造函数(私有authService:authService){}
ngOnInit(){}
get isActivated():可观察{
返回this.authService.isLogIn;
}
}
所以这里我只是用一个get函数直接将可观测数据传递给我们的模板。因此,在模板中,我将实现AsyncPipe,如下所示:

<div *ngIf="!(isActivated | async) else user">
   <a class="nav-item nav-link text-white anchor-hover" routerLink="/login"
     routerLinkActive="active font-weight-bold">
    <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
  </a>
</div>
<ng-template #user>
  <!--DROPDOWN PROFILE-->
  <div class="btn-group" role="group" *ngIf="authService.user">
    <button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
      {{authService.user.displayName}}
    </button>
    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
      <a class="dropdown-item" href="#">Dropdown link</a>
      <a class="dropdown-item" href="#">Dropdown link</a>
    </div>
  </div>
  <a class="nav-item nav-link text-white anchor-hover"
     routerLink="/dashboard"
     routerLinkActive="active font-weight-bold">
    <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
  </a>
</ng-template>


我将尝试帮助/回答,请注意,有很多代码需要筛选,因此我可能遗漏了一些明显的内容。无论如何,为了整理代码并为您指明正确的方向,您可能需要查看AsyncPipe

我想首先修改您的AuthService,通过改变
isLogIn=newsubject()
to
private\u isLogIn=new Subject()。我们不想将主题共享给其他将修改它的组件,因此在AuthService中的任何地方,您都只需要添加下划线。。。最后,要导出要使用的主题,我们可以添加如下get函数:

get isLogIn(): Observable<boolean> {
   return this._isLogIn.asObservable();
}
export class HeaderComponent implements OnInit {
  constructor(private authService: AuthService) { }

  ngOnInit() {}

  get isActivated(): Observable<boolean> {
    return this.authService.isLogIn;
  }
}
现在,如果我要编写您的
header.component.ts
,我会这样做:

get isLogIn(): Observable<boolean> {
   return this._isLogIn.asObservable();
}
export class HeaderComponent implements OnInit {
  constructor(private authService: AuthService) { }

  ngOnInit() {}

  get isActivated(): Observable<boolean> {
    return this.authService.isLogIn;
  }
}
导出类HeaderComponent实现OnInit{
构造函数(私有authService:authService){}
ngOnInit(){}
get isActivated():可观察{
返回this.authService.isLogIn;
}
}
所以这里我只是用一个get函数直接将可观测数据传递给我们的模板。因此,在模板中,我将实现AsyncPipe,如下所示:

<div *ngIf="!(isActivated | async) else user">
   <a class="nav-item nav-link text-white anchor-hover" routerLink="/login"
     routerLinkActive="active font-weight-bold">
    <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Ingresar
  </a>
</div>
<ng-template #user>
  <!--DROPDOWN PROFILE-->
  <div class="btn-group" role="group" *ngIf="authService.user">
    <button id="btnGroupDrop1" type="button" class="btn btn-light dropdown-toggle pointer" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
      {{authService.user.displayName}}
    </button>
    <div class="dropdown-menu dropdown-menu-right" aria-labelledby="btnGroupDrop1">
      <a class="dropdown-item" href="#">Dropdown link</a>
      <a class="dropdown-item" href="#">Dropdown link</a>
    </div>
  </div>
  <a class="nav-item nav-link text-white anchor-hover"
     routerLink="/dashboard"
     routerLinkActive="active font-weight-bold">
    <i class="fa fa-sign-in pr-2" aria-hidden="true"></i>Dashboard
  </a>
</ng-template>


您还可以在AuthService中处理
firebase.auth().onAuthStateChanged
,然后在AppModule的构造函数中实例化该服务。我没有注意到您在AuthService中没有这样做。我已经按照您的步骤进行了操作,但是现在如何将值设置为isLogIn?使用set?我不知道您是否看到了我的评论,但我没有注意到您没有在authservice中查看用户状态,因此我建议您将其移动到那里。(参见上面的评论)我已经将firebase逻辑更改为AuthService,并从AppModule调用它,但在标题中我仍然看不到与ngIf相关的元素。如果你想,我无法在github上创建一个repo并与你共享。我想你的意思是说你可以与我共享该repo,所以请,我将尽最大努力提供帮助。此外,你还可以在AuthService中处理
firebase.auth().onAuthStateChanged
,然后在AppModule的构造函数中实例化该服务。我没有注意到您在AuthService中没有这样做。我已经按照您的步骤进行了操作,但是现在如何将值设置为isLogIn?使用set?我不知道您是否看到了我的评论,但我没有注意到您没有在authservice中查看用户状态,因此我建议您将其移动到那里。(参见上面的评论)我已经将firebase逻辑更改为AuthService,并从AppModule调用它,但在标题中我仍然看不到与ngIf相关的元素。如果你想,我不能在github上创建回购协议并与你共享。我想你的意思是说你可以与我共享回购协议,所以请,我会尽最大努力帮助你。