【问题标题】:How to implement BehaviorSubject with getter and setter in Angular 2如何在 Angular 2 中使用 getter 和 setter 实现 BehaviorSubject
【发布时间】:2016-10-07 10:18:45
【问题描述】:

我正在尝试在我的 LoginService 中实现 isLoggedIn 类型为 BehaviorSubject 的布尔值以及 getter 和 setter 函数,以将值作为 Observable 获取/通过其 BehaviorSubject 正确设置变量。这是有效的,但是它在 TSLint 中引发了两个关于“类型不可分配”和“重复标识符”的错误。在没有 TSLint 抱怨的情况下定义它的正确方法是什么。

这是上述代码的精简版:

@Injectable()
export class LoginService {
  public isLoggedInSource = new BehaviorSubject<boolean>(false);
  public isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable(); // Duplicate identifier 'isLoggedIn'.

  constructor(private http: Http) {}

  set isLoggedIn(logged): void { // Duplicate identifier 'isLoggedIn'.
    this.isLoggedInSource.next(logged);
  }

  get isLoggedIn(): Observable<boolean> { // Duplicate identifier 'isLoggedIn'.
    return this.isLoggedInSource.asObservable();
  }

  logout() {
    this.isLoggedIn = false; // Type 'boolean' is not assignable to type 'Observable<boolean>'.
  }

  login(body) {
    return this.http.post('/login', body)
        .map(res => {
                if (res.token) {
                  this.isLoggedIn = true; // Type 'boolean' is not assignable to type 'Observable<boolean>'.
                }
                return res;
              })
        .catch(err => Observable.throw(err););
  }
}

【问题讨论】:

  • 对属性和 getter/setter 使用不同的名称。
  • 还... 为公共财产使用 getter/setter 并没有什么意义。无论如何,您班级的用户都可以绕过他们。

标签: angular typescript getter-setter tslint behaviorsubject


【解决方案1】:

当你使用 TypeScript getter/setter 时,你必须重命名你的属性,所以属性名称应该与 getters/setters 名称不同。

此外,您可以通过将behaviorSubject 设置为服务的私有成员来修改您的代码,并且只需公开您的Observable

@Injectable()
export class LoginService {

  private isLoggedInSource = new BehaviorSubject<boolean>(false);

  public _isLoggedIn: Observable<boolean> = this.isLoggedInSource.asObservable();

  constructor() {}

  set isLoggedIn(logged: boolean) {
    this.isLoggedInSource.next(logged);
  }

  get isLoggedIn() {
    return this._isLoggedIn;
  }

  logout() {
    this.isLoggedIn = false;
  }

  login() {
    this.isLoggedIn = true;
  }

} 

你将能够听到你的组件的变化:

export class App {
  constructor(private loginService: LoginService) {

    loginService.isLoggedIn.subscribe(bool => console.log(bool));

    //Wait and simulate a login
    setTimeout(() => {
      loginService.login();
    }, 1200);

  }
}

【讨论】:

  • 你将如何使用这种模式解决错误处理?
  • 您可以在服务层处理您的错误。但是您不能将new Error() 之类的内容发送到主题流,因为它会杀死它。您应该将架构分为两部分:数据生成流程数据存储。可以参考这个post
  • 我收到了error TS2380: 'get' and 'set' accessor must have the same type.
  • 没错,getter 和 setter 应该有相同的类型。所以这不是一个选择。
  • 上面的代码不起作用。您不能在 getter 中返回 observable,并在 setter 中为同一属性输入一个布尔值。
猜你喜欢
  • 2017-12-07
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
相关资源
最近更新 更多