【问题标题】:Change content of NavBar in Angular based on ngIf condition根据 ngIf 条件更改 Angular 中 NavBar 的内容
【发布时间】:2019-11-01 18:05:04
【问题描述】:

我是 Angular 和 Node JS 的初学者。我正在尝试根据 ngIf 条件更改简单的导航栏。但是,它似乎不起作用。

我已经尝试过使用静态成员变量。

另外,尝试创建一个方法来更改navbar.component 中isUserAuthenticated 的值,并调用homepage.component 和dashboard.component 中的方法。

我也完成了console.log() 并检查了isUserAuthenticated 变量的值。它正在homepage.component 和dashboard.component 上进行更新。但是,NavBar 始终保持不变。

我已经直接在 navbar.component 中更改了值,然后它就可以工作了。所以,我想知道为什么如果我更改其他组件的值它不起作用。

navbar.component.html

       <div *ngIf="!isUserAuthenticated">
          <li class="nav-item">
            <a class="nav-link" href="/"> EX FALSE </a>
          </li>
        </div>

        <div *ngIf="isUserAuthenticated">
          <li class="nav-item">
            <a class="nav-link" href="/"> EX TRUE </a>
          </li>
        </div>

navbar.component.ts

import { Component, OnInit } from '@angular/core';

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

  isUserAuthenticated = true;

  constructor() { }

  ngOnInit() { }

  public authenticate() {
    this.isUserAuthenticated = false;
    return  this.isUserAuthenticated;
  }
  public deauthenticate() {
    this.isUserAuthenticated = true;
    return  this.isUserAuthenticated;
  }
}

homepage.component.ts

import { Component, OnInit } from '@angular/core';
import { NavbarComponent } from '../navbar/navbar.component';


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

  constructor( ) {

  }

  ngOnInit() {

    console.log("here");
    this.deauthenticate();


  }

  public deauthenticate()
  {
    const comp2 = new NavbarComponent();
    comp2.deauthenticate();
    console.log(comp2.deauthenticate());
  }
}

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { NavbarComponent } from '../navbar/navbar.component';



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

  constructor( ) {
  }

  ngOnInit() {

    this.authenticate();
  }

  public authenticate()
  {
    const comp2 = new NavbarComponent();
    comp2.authenticate();
    console.log(comp2.authenticate());
  }

}

我希望dashboard 组件在导航栏中显示“EX TRUE”,而homepage 组件在导航栏中显示“EX FALSE”。

【问题讨论】:

  • 您应该使用一些服务来管理您的身份验证状态并创建不属于渲染视图的新组件,这就是您的方法调用不做任何事情的原因
  • 这个问题现在看起来不一样了,您是想为身份验证设置全局状态,还是只为每个显示位置设置本地状态?
  • 感谢您的回答。它现在正在工作。我赞成您的回答并标记为正确。再次感谢您。

标签: node.js angular web-applications node-modules


【解决方案1】:

正如评论中提到的,您需要创建身份验证服务check this for full example

@Injectable()
export class AuthenticationService {
  authenticated$: BehaviorSubject<boolean> = new BehaviorSubject(false);

  public authenticate() {
    this.authenticated$.next(true);
  }

  public deauthenticate() {
    this.authenticated$.next(false);
  }
}

您以这种方式注入它以便能够在模板中使用它

import { Component } from '@angular/core';

import { AuthenticationService } from '../authentication/authentication.service';

@Component({
  selector: 'my-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: [ './navbar.component.css' ]
})
export class NavbarComponent {
  constructor(
    public authenticationService: AuthenticationService,
  ) {
  }
}

然后在模板中你可以这样做

Authenticated {{ authenticationService.authenticated$ | async }}

<div *ngIf="(authenticationService.authenticated$ | async) === true">
  <li class="nav-item">
    <a class="nav-link" href="/">EX TRUE</a>
  </li>
</div>

<div *ngIf="(authenticationService.authenticated$ | async) === false">
  <li class="nav-item">
    <a class="nav-link" href="/">EX FALSE</a>
  </li>
</div>

<button (click)="authenticationService.authenticate()">Authenticate</button>
<button (click)="authenticationService.deauthenticate()">Deauthenticate</button>

虽然我建议在这种情况下使用 ngSwitch:

<div>
  <li class="nav-item" [ngSwitch]="authenticationService.authenticated$ | async">
    <a class="nav-link" href="/" *ngSwitchCase="true">EX TRUE</a>
    <a class="nav-link" href="/" *ngSwitchDefault>EX FALSE</a>
  </li>
</div>

此外,如果您想为网站的某些部分设置单独的状态,您可以这样做:

@Component({
  selector: 'my-homepage',
  templateUrl: './homepage.component.html',
  styleUrls: [ './homepage.component.css' ],
  // this way you have a separate instance of AuthenticationService here anything that will use this service and is rendered under this component will use a localized version of this service
  providers: [AuthenticationService],
})
export class HomepageComponent {
  constructor(
    public authenticationService: AuthenticationService,
  ) {
  }
}

【讨论】:

  • 非常感谢。我快到了。它与您提供的 NavBar 一起使用。请让我知道如何在 *ngIf 中引用 authenticationService.authenticated$。例如,我想做如下的事情:&lt;div *ngIf="!authenticationService.isUserAuthenticated$ | async "&gt; &lt;a class="nav-link" href="/"&gt; EX FALSE &lt;/a&gt; &lt;/div&gt; &lt;div *ngIf="authenticationService.isUserAuthenticated$ | async "&gt; &lt;a class="nav-link" href="/"&gt; EX TRUE &lt;/a&gt; &lt;/div&gt;
  • for ngIf 是 *ngIf="(authenticationService.authenticated$ | async) === true" 或 false 在其他情况下
  • 我还添加了 ngSwitch 的示例,在这两个值的情况下应该更好,只需刷新我的答案
  • 它正在工作。太感谢了。这真的很有帮助。我会努力学习这种Angular的基本概念。
  • 我在示例中添加了更多描述,如果有任何不清楚的地方,您可以查看更新版本
【解决方案2】:

事情不是这样设计的。对于这种情况,您需要创建一个Service,例如AuthService,它将在两个组件之间共享。

AuthEventSvc

export class AuthEventSvc{

   private authEvent = new BehaviorSubject<boolean>(true);
   constructor(){}

   emitAuthStatus(state: boolean){
     this.authEvent.next(state);
   }

   authListener(){
     return this.authEvent.asObservable();
   }

}

然后从 HomeComponent

发出
export class HomepageComponent implements OnInit {

  constructor(private authEvent: AuthEventSvc ) {

  }

  ngOnInit() {
    this.authEvent.emitAuthStatus(false);
  }
}

并在 NavBarComponent

中订阅它
export class NavbarComponent implements OnInit {

  isUserAuthenticated = true;
  authSubscription : Subscription;

  constructor(private authEvent: AuthEventSvc) { }

  ngOnInit() { 
    this.authSubscription = this.authEvent.authListener().subscribe(state => {
      this.isUserAuthenticated = state;
    })
  }

  ngOnDestroy(){
    this.authSubscription.unsubscribe(); // make sure to unsubscribe
  }

}

您还应该阅读有关 how change detection works 以及如何在 Angular 中使用 NgZone 以获得更清晰的信息,因为这些主题需要长篇文章来解释。我只是给你一些面包屑来帮助你更好地理解:)

【讨论】:

  • 非常感谢您的帮助。我是 Angular 和 NodeJS 的新手,所以它真的会帮助我更好地理解你的解释。您能否让我知道在哪里创建 AuthService。它是一个组件吗?
  • @harshpamnani AuthService 是一项服务(component 是不同的东西)。我强烈建议您熟悉angular 的基本功能。在您创建所有其他组件的同一模块中创建此服务。确保把@Injectable 和所有使用它。我曾经在探索 angular 时创建了一个 git repo github.com/shashankvivek/Angular4。看看它是否对你也有帮助:) 干杯。
  • 当然。非常感谢您的快速回复。我一定会看看 git repo,标记并支持答案。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2011-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
相关资源
最近更新 更多