从组件中使用的服务刷新公共可观察对象

时间:2016-08-19 20:33:00

标签: angular rxjs

有3个文件:

  • 处理登录和注销的AuthService
  • 包含/ login,/ logout链接
  • 的TopbarComponent
  • 上面组件中使用的topbar.component.html文件

我的问题是我试图将AuthService中的isLogged变量作为一个可观察对象来观察"观察"它在TopbarComponent中更新html文件中的值。

我认为如果我将isLogged作为@Input()放在TopbarComponent中会有效,但必须有更好的方法。

更新的文件

auth.service.ts



import { Injectable } from '@angular/core';
import {Response} from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Subject } from 'rxjs/Subject';

//
import {HttpService} from "./http.service";
import {LocalStorageService} from "./local-storage.component";

@Injectable()
export class AuthenticationService {

    public isLoggedIn:Subject<boolean> = new Subject<boolean>();

    constructor(
        private httpService: HttpService,
        private localStorageService: LocalStorageService
    ) {
        var user = this.localStorageService.getItem('user');
        this.isLoggedIn.next(!!(user && user.token));
    }

    login(email, password): Observable<boolean> {

        return this.httpService.call('post', 'login', JSON.stringify({ email: email, password: password }))
            .map((response: Response) => {
                // login successful if there's a jwt token in the response
                let token = response.json() && response.json().token;

                if (token) {
                    this.isLoggedIn.next(true);
                    // store email and jwt token in local storage to keep user logged in between page refreshes
                    this.localStorageService.setItem('user', JSON.stringify({ email: email, token: token }));
                    // return true to indicate successful login
                    return true;
                } else {
                    // return false to indicate failed login
                    return false;
                }
            });
    }

    logout(): void {
        this.isLoggedIn.next(false);
        // clear token remove user from local storage to log user out
        this.localStorageService.removeItem('user');

    }

    signup(email, password): Observable<boolean> {
        return this.httpService.call('post', 'signup', JSON.stringify({ email: email, password: password }))
            .map((response: Response) => (response.status === 201) ? true : false);
    }
}
&#13;
&#13;
&#13;

topbar.component.ts

&#13;
&#13;
import {Component, OnInit} from "@angular/core";
//
import {SearchBoxComponent} from "../search-box/search-box.component";
import {AuthenticationService} from "../services/auth.service";
import {UserService} from "../services/user.service";

declare const module;

@Component({
    selector: 'topbar',
    moduleId: module.id,
    directives: [SearchBoxComponent],
    templateUrl: 'topbar.component.html',
    styleUrls: ['topbar.component.css']
})
export class TopbarComponent implements OnInit {
    constructor(
        private authenticationService: AuthenticationService,
        private userService: UserService) {

    }

    ngOnInit() {
        this.authenticationService.isLoggedIn.subscribe(
            observer => console.log(observer))
    }

}
&#13;
&#13;
&#13;

topbar.component.html

&#13;
&#13;
<header class="topbar">
    <h1 routerLink="/">homepage</h1>
    <search-box></search-box>
    <a routerLink="/login" *ngIf="!(authenticationService.isLoggedIn | async)">Login</a>
    <a routerLink="/signup" *ngIf="!(authenticationService.isLoggedIn | async)">Signup</a>
    <a routerLink="/logout" *ngIf="(authenticationService.isLoggedIn | async)">Logout</a>
    <a [routerLink]="[{outlets: {userbar:'userbar'}}]"
       *ngIf="(authenticationService.isLoggedIn | async)">{{userService?.user?.email}}</a>
    <a [routerLink]="[{outlets: {userbar:null}}]"
       *ngIf="(authenticationService.isLoggedIn | async)">{{userService?.user?.email}}</a>
</header>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

尝试以下,

<强> auth.service.ts

  import { Subject } from 'rxjs/Subject';

  // change observable to subject
  public isLogged:Subject<boolean> = new Subject<boolean>();

  // to set value use below
  this.isLogged.next(true);   //  this.isLogged.next(false);
模板中的

使用async管道。

<强> topbar.component.html

 *ngIf="(authenticationService.isLogged | async)"

希望这会有所帮助!!

答案 1 :(得分:1)

如果最初的想法是检查用户是否登录,您还可以尝试其他选项:

<强> AuthService

constructor(http: Http) {}
public isLoggedIn(): Observable<any> {
    var user = this.localStorageService.getItem('user');
    if(user){
        return Observable.of(true);  
    } else {
        // Also return Observable after call, where tokenAPiUrl is AbstractAPI
        return this.http.get('tokenApiUrl'); 
    }
}

<强> topbar.component.ts

ngOnInit() {
    this.authenticationService.isLogged().subscribe(
        observer => console.log(observer))
}

您可以在任何地方注入authService并检查用户是否登录,并在用户登录凭据检查后添加一些逻辑。