首页 文章

Angular 2 Observables无法分配给布尔值

提问于
浏览
2

我试图在角度2中使用Observables来观察对名为loggedIn的布尔值的简单更改,该布尔值可以是true或false . 我在TS中收到此错误 .

类型'boolean'不能分配给'Subject'类型 . 类型'boolean'不能分配给'Observable'类型 .

有人可以提供替代方案或告诉我我做错了什么吗?

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import {Subject} from "../../node_modules/rxjs/src/Subject";
import {Observable} from "../../node_modules/rxjs/src/Observable";


@Injectable()
export class UserService {

  user: Subject<any>;
  user$: Observable<any>;
  //loggedIn: Subject<any>;
  //loggedIn$: Observable<any>;
  loggedIn: boolean;

  constructor(private http: Http) {
    this.user = new Subject();
    this.user$ = this.user.asObservable();
    this.loggedIn = false;
    //this.loggedIn = new Subject();
    //this.loggedIn$ = this.user.asObservable();


  }

  createAccount(user) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');



    return this.http
      .post(
        '/api/accounts',
        JSON.stringify(user),
        { headers }
      )
      .map(res => res.json())
      .map((res) => {
        if (res['success']) {
          localStorage.setItem('auth_token', res['auth_token']);
          //this.loggedIn$ = true;
          //this.loggedIn.next(true);
        }

        return res['success'];
      });
  }

  login(user) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');

    return this.http
      .post(
        '/api/authenticate',
        JSON.stringify(user),
        { headers }
      )
      .map(res => res.json())
      .map((res) => {
        console.log('Login Result:', res.user);
        if (res["success"]) {
          localStorage.setItem('jwt', res.token);
          //set user service info...
          //this.user.next(res.user[0]);
          //this.loggedIn.next(true);
        }
        return res;
      });
  }

  updateAccount(user) {
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    headers.append('x-access-token', localStorage.getItem('jwt'));

    console.log('PAYLOAD FOR UPDATE USER: ' , user);

    return this.http
      .put(
        '/api/accounts/' + user._id,
        JSON.stringify(user),
        { headers }
      )
      .map(res => res.json())
      .map((res) => {
        if (res['success']) {
          localStorage.setItem('auth_token', res['auth_token']);
          //this.loggedIn$ = true;
          //this.loggedIn.next(true);
        }

        return res['success'];
      });
  }

  logout() {
    localStorage.removeItem('auth_token');
    //this.loggedIn$ = false;
    //this.loggedIn.next(false);
  }

}

请查看已注释掉的行 . 我需要订阅Observable,它会随时返回true或false .

1 回答

  • 1

    使用主题发出值 . 如果要在订阅时发出状态但不想要初始状态,请使用 private loggedIn: ReplaySubject<boolean> new ReplaySubject(1); . 如果您想要初始状态,请使用 private loggedIn: BehaviorSubject<boolean> = new BehaviorSubject(false); .

    不要将主题作为公共属性呈现 - 只暴露可观察对象,即 loggedIn$: Observable<boolean> = this.loggedIn.asObservable(); . 服务的消费者应该只能通过公共方法以受控方式改变国家 .

    这些是您的服务中与登录状态有关的部分内容 .

    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable, ReplaySubject } from 'rxjs';
    
    @Injectable({
      providedIn: 'root',
    })
    export class UserService {
      private readonly loggedIn: ReplaySubject<boolean> = new ReplaySubject(1);
    
      readonly loggedIn$: Observable<boolean> = this.loggedIn.asObservable();
    
      constructor(private readonly http: HttpClient) {}
    
      login(user): Promise<any> {
        return this.http
          .post(/* (...) */)
          .map((res) => {
            if (res["success"]) {
              this.loggedIn.next(true);
            }
          });
      }
    
      logout(): void {
        this.loggedIn.next(false);
      }
    }
    

    所以我们在public loggedIn$ 属性中将状态公开为 Observable<boolean> ,这只是private loggedIn subject属性的 Observable 接口 . 通过向 loggedIn 发送一个值来改变状态,该值由 loggedIn$ 的订户观察到 .

相关问题