将本地变量值订阅到Angular中另一个组件中的Observable变量

时间:2020-04-05 14:21:01

标签: html angular typescript observable

我想基于本地变量通过*ngIf更改HTML视图,该视图应基于通过共享服务的可观察对象传递的变量进行更改。

HTML

<div class="login-container" *ngIf="!isAuthenticated">

相同组件的TypeScript:

export class LoginComponent implements OnInit {
  authenticationsSubscription;
  isAuthenticated: boolean;

  constructor(
    private authService: AuthServiceService,
    private router: Router,
    private route: ActivatedRoute){}

  getAuth(): Observable<boolean>{
    return this.authService.validation();
  }

  ngOnInit() {
    this.authenticationsSubscription = this.authService.validation().subscribe(auth => this.isAuthenticated = auth);
  }
} 

共享服务AuthService的TypeScript:

export class AuthServiceService {
  isAuthenticated: boolean;

  validation(): Observable<boolean>{
    return of(this.isAuthenticated);
  }
}

在调试过程中,我发现,随着AuthService变量isAuthenticated的更改,LoginComponent中的变量isAuthenticated不会更改。我还尝试使用pipe()tap(),它们没有任何改变。

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

将您的AuthServiceService转换为具有身份验证状态的BehaviorSubject,然后将其返回为Observable,如下所述。

import { Observable, BehaviorSubject } from "rxjs";

export class AuthServiceService {
  private isAuthenticatedSub: BehaviorSubject<boolean> = new BehaviorSubject(false);

  set isAuthenticated(isAuthenticated: boolean) {
    this.isAuthenticatedSub.next(isAuthenticated);
  }

  get isAuthenticated(): boolean {
    return this.isAuthenticatedSub.value;
  }

  validation(): Observable<boolean> {
    return this.isAuthenticatedSub.asObservable();
  }
}

答案 1 :(得分:1)

在初始化组件时触发OnInit生命周期挂钩时,observable的实际订阅只会发生一次。

您可以订阅BehaviorSubject来捕捉价值变化。

Stackblitz example

AuthService

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable()
export class AuthService {
  isAuthenticated: BehaviorSubject<boolean>;

  constructor() {
    this.isAuthenticated = new BehaviorSubject<boolean>(false);
   }
}

组件

import { Component, OnInit } from '@angular/core';
import { AuthService } from './auth.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  isAuthenticated: Observable<boolean>;

  constructor(private authService: AuthService) {}

  ngOnInit() {
    this.isAuthenticated = this.authService.isAuthenticated;
  }

  login() {
    this.authService.isAuthenticated.next(true);
  }

  logout() {
    this.authService.isAuthenticated.next(false);
  }
}

模板

<div *ngIf="isAuthenticated | async; else notAuthenticated">
  User is authenticated
  </div>

  <ng-template #notAuthenticated>
  <div>User isn't authenticated</div>
  </ng-template>

  <button (click)="login()">Login</button>
  <button (click)="logout()">Logout</button>