【问题标题】:Angular 8 *ngIf does not reflect the UI properly in the navigation barAngular 8 *ngIf 无法在导航栏中正确反映 UI
【发布时间】:2020-05-29 07:52:03
【问题描述】:

我正在尝试将 bootstrap@4 集成到 Angular 8 应用程序中,以使其完全响应。

如果用户未注册(注册)或未登录,导航栏中的某些元素应隐藏(注销 btn 或链接),如果他已登录,则应隐藏其他元素(登录 btn 或链接)。

为了更清楚地说明情况,下面是代码的 sn-ps,其中 header.ts 文件包含验证用户对象是否存在。这是通过 .ts 文件构造函数中的服务注入来完成的。回想起来,该服务会调用 firebase REST API 来检查身份验证的有效性。

通过有效的身份验证后,登录 btn 或链接应该会消失,而会出现一个注销元素。

这是部分工作。我从登录界面(表单)导航到另一个组件(服务),但导航栏没有分别更新。登录前还是一样的ui。

任何提示或建议如何解决这个问题? 是因为bootstrap@4吗? (控制台没有错误)

提前致谢

import { Component, OnInit, OnDestroy } from '@angular/core';
import { AuthService } from 'src/app/auth/auth.service';
import { Subscription } from 'rxjs';


@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit, OnDestroy {
  isAuthenticated = false;
  private userSub: Subscription; 
  
  constructor(private authservice: AuthService) { }

  ngOnInit() {
    this.userSub = this.authservice.user.subscribe(user =>{
      this.isAuthenticated = !!user;
    }
    );
  }
  
  ngOnDestroy(){
    this.userSub.unsubscribe();
  }
}
<nav class="navbar navbar-expand-md navbar-light bg-light  sticky-top">
   <div class="container-fluid">
       <a class="navbar-brand" href="#"><img src="assets/img/logo.png"></a>
        <button 
        class="navbar-toggler" 
        type="button" 
        data-toggle="collapse"
        data-target="#navbarResponsive">
       <span class="navbar-toggler-icon"></span>
        </button> 
        <div class="collapse navbar-collapse" id="navbarResponsive">
               <ul class="navbar-nav ml-auto">
               <li>
                   <a class="nav-link" routerLink="/home" routerLinkActive="active" style="cursor: pointer;">Home</a>
               </li>
                <li>
                   <a class="nav-link" routerLink="/about" routerLinkActive="active" style="cursor: pointer;">About</a>
               </li>
                <li  routerLinkActive="active">
                   <a class="nav-link" routerLink="/services"  style="cursor: pointer;">Services</a>
               </li>
                <li  routerLinkActive="active">
                   <a class="nav-link" routerLink="/team"  style="cursor: pointer;">Team</a>
               </li>
                <li   routerLinkActive="active" *ngIf="!isAuthenticated">
                   <a class="nav-link" routerLink="/auth"  style="cursor: pointer;" > Login | Sign up </a>
             </li>
             <li   routerLinkActive="active" *ngIf="isAuthenticated">
                <a class="nav-link" routerLink="/auth"  style="cursor: pointer;" > Logout </a>
          </li>
          
           </ul>
        </div>
   </div>
   </nav>

【问题讨论】:

  • 这不是引导程序,所以让我们排除它。就身份验证处理而言,您的示例以独立的方式看起来很好。所以它必须是标题组件如何放置在应用程序中和/或身份验证服务如何运行的上下文。您能否将 html 缩减为相关部分并向我们展示服务以及标头的使用方式。
  • 尝试删除!!从'this.isAuthenticated = !!user; ' 并使用一些逻辑来代替 if else
  • @Bozhinovski 怎么了!!在这种情况下?对我来说似乎很好用。
  • 没有什么真正想测试它的 undefined 但这似乎很好,可能他可以尝试将 isAuthenticated 包装到服务调用中或尝试使用 onPush 检测策略

标签: html angular typescript bootstrap-4 angular-ng-if


【解决方案1】:

这很奇怪。

@kurt Hamilton,下面是服务

import { Component } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Observable } from 'rxjs';

import { AuthService } from './auth.service';
import { AuthResponseData} from'./auth.service'
import { Router } from '@angular/router';

@Component({
  selector: 'app-auth',
  templateUrl: './auth.component.html',
  styleUrls: ['./auth.component.css']
})

export class AuthComponent  {


  isLoginMode= true;
  error: string = null;
  constructor(private authservice: AuthService, private router: Router ){}

  onSwitchMode() {
    this.isLoginMode = !this.isLoginMode;
  } 
  onSubmit(form: NgForm){
    if(!form.valid){
    return;  
    }

    const email= form.value.email;
    const password= form.value.password;
    
   let authObs : Observable<AuthResponseData>;
    if(this.isLoginMode){
     authObs = this.authservice.login(email, password);

    }else{
    authObs =  this.authservice.signUp(email, password);
    }

    authObs.subscribe(
      response =>{
      console.log(response);
      this.router.navigate(['/services']);
      
    },
    errorMessage =>{
      console.log(errorMessage); 
      this.error = errorMessage;
    }
    );  
    form.reset();
  }
}

非常感谢,但我不明白这一点。如果您有解决方案,请告诉我!再次感谢。

@Fmerco,我确实订阅了 auth.component.ts 中的 observables(包括在下面)

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import {catchError, tap} from 'rxjs/operators'
import { throwError, Subject } from 'rxjs';
import { User } from './user.model';

export interface AuthResponseData {
    idToken: string; 
    email: string; 
    refreshToken: string;
    expiresIn: string;
    localId: string;
    registered?: boolean;
  }

@Injectable({providedIn: 'root'})
export class AuthService{

    user = new Subject <User>();
    constructor(private http: HttpClient){}

    signUp( email: string , password: string){
      return  this.http.post<AuthResponseData>(
            'https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[key-omitted]',
            {
                email: email, 
                password: password, 
                returnSecureToken: true
            }     
        ).pipe(catchError (this.handleError), tap(resData =>{
            this.handleAuthentication(
                resData.email, 
                resData.localId, 
                resData.idToken, 
                +resData.expiresIn);
        }));        
    }
    login(email: string, password: string){
       return this.http.post<AuthResponseData>(
        'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[key-omitted]',
        {
            email: email, 
            password: password, 
            returnSecureToken: true
        }
        ).pipe(catchError (this.handleError)); 
        }

    private handleAuthentication(email: string, userId: string, token: string, expiresIn: number){
        
        const expirationDate = new Date(new Date().getTime() + expiresIn * 1000);

        const user = new User(
            email, 
            userId,
            token, 
            expirationDate
            );
            this.user.next(user);
    }

    private handleError(errorRes: HttpErrorResponse){
        let errorMessage = 'An unknown error occured';
        if(!errorRes.error || !errorRes.error.error){
            return throwError(errorMessage);
        }
        switch(errorRes.error.error.message){
            case 'EMAIL_EXISTS':
              errorMessage = 'This email already exists'
               break; 
            case 'EMAIL_NOT_FOUND': 
            errorMessage = 'This email does not exist'
               break; 
            case 'INVALID_PASSWORD': 
            errorMessage= 'Incorrect password'
               break;

          }
          return throwError(errorMessage);
    }
}

【讨论】:

  • 其实sn-ps是反对的!无论如何都要检查一下。
猜你喜欢
  • 2020-04-02
  • 2018-06-29
  • 1970-01-01
  • 2017-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-21
  • 2011-10-28
相关资源
最近更新 更多