Подпишите локальную переменную Value в Observable переменной в другом компоненте в Angular - PullRequest
1 голос
/ 05 апреля 2020

Я хочу изменить HTML представление с помощью *ngIf на основе локальной переменной, которая должна меняться в зависимости от переменной, доставленной через наблюдаемую из общего сервиса.

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);
  }
} 

TypeScript общего сервиса AuthService:

export class AuthServiceService {
  isAuthenticated: boolean;

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

Во время отладки я обнаружил, что переменная isAuthenticated в LoginComponent не изменяется при изменении переменной isAuthenticated AuthService. Я также попытался использовать pipe() и tap(), что ничего не изменило.

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Фактическая подписка вашей наблюдаемой будет происходить только один раз, когда ловушка жизненного цикла OnInit срабатывает при инициализации компонента.

Вы можете подписаться на BehaviorSubject, чтобы поймать изменения значения.

Пример Stackblitz

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>
1 голос
/ 05 апреля 2020

Преобразуйте ваш 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();
  }
}
...