Как реализовать BehaviorSubject с геттером и сеттером в Angular 2

Я пытаюсь реализовать в своем LoginService isLoggedIn логическое значение типа BehaviorSubject вместе с функциями получения и установки, чтобы получить значение как 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););
  }
}

person Marcello di Simone    schedule 07.10.2016    source источник
comment
используйте разные имена для свойства и геттеров / сеттеров.   -  person toskv    schedule 07.10.2016
comment
также ... на самом деле нет смысла иметь геттер / сеттер для общедоступного свойства. Пользователи вашего класса в любом случае смогут их обойти.   -  person toskv    schedule 07.10.2016


Ответы (1)


Когда вы используете TypeScript getter/setter, вам нужно переименовать свое свойство, поэтому имя свойства должно отличаться от getters/setters name.

Более того, вы можете изменить свой код, установив свой 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);

  }
}
person Paul Boutes    schedule 07.10.2016
comment
Как бы вы разрешили обработку ошибок с помощью этого шаблона? - person martinoss; 08.06.2017
comment
Вы можете обрабатывать свои ошибки на уровне обслуживания. Но вы не можете отправить что-то вроде new Error() в тематический поток, потому что это убьет его. Вы должны разделить вашу архитектуру на две части: поток генерации данных и хранилище данных. Вы можете обратиться к этому сообщение - person Paul Boutes; 08.06.2017
comment
Я получаю error TS2380: 'get' and 'set' accessor must have the same type. - person DeanB_Develop; 19.04.2018
comment
Верно, геттер и сеттер должны иметь один и тот же тип. Так что это не вариант. - person liqSTAR; 30.07.2019