Angular2 - подписаться на изменения служебной переменной

У меня есть служба проверки подлинности, которая делает аутентифицированную переменную равной true или false.

checkAuthentication(){
  this._authService.getAuthentication()
    .subscribe(value => this.authenticated = value);
}

Как выполнить функцию, когда this.authenticated изменило значение? ngOnChanges не подбирает изменения.

Ответ 1

Чтобы сохранить authenticated в сервисе и поделиться им между компонентами, которые вы можете использовать BehaviorSubject, он value проверяет аутентификацию в разных местах, а метод subscribe() реагирует на изменение...

class AuthService {
  public authenticated = new BehaviorSubject(null);
  getAuthentication() {
    this._http.get('/authenticate')
      .map(response => response.json())
      .map(json => Boolean(json)) // or whatever check you need...
      .subscribe((value: boolean) => this.authenticated.next(value))
  }
}

class Component {
  constuctor(private _authService: AuthService) {
    // Only check once even if component is 
    // destroyed and constructed again
    if (this._authService.authenticated.value === null)
      this._authService.getAuthentication();
  }

  onSubmit(){
    if (!this._authService.authenticated.value)
      throw new Error("You are authenticated!")
  }
}

Как выполнить функцию, когда this.authenticated изменило значение?

  this._authService.authenticated
   .subscribe((value: boolean) => console.log(value))

Ответ 2

Я думаю, что вы могли бы использовать синтаксис get/set для TypeScript, чтобы определить, когда обновляется ваше аутентифицированное свойство вашей службы:

  private _authenticated:Boolean = false;
  get authenticated():Boolean {
        return this._authenticated ;
  }
  set authenticated ( authenticated Boolean) {
    // Plugin some processing here
      this._ authenticated = authenticated;
  }

При назначении значения вызывается блок "set authenticated". Например, с таким кодом:

this.authenticated = true;

См. этот вопрос для получения дополнительной информации:

Тем не менее, вы также можете использовать свойство EventEmitter в сервисе. Когда аутентифицированное свойство обновляется, соответствующее событие может быть запущено.

export class AuthService {
  authenticatedChange: Subject<boolean> = new Subject();

  constructor() {}

  emit(authenticated) {
    this.authenticatedChange.next(authenticated);
  }

  subscribe(component, callback) {
    // set 'this' to component when callback is called
    return this.authenticatedChange.subscribe(data => {
      callback(component, data);
    });
  }
}

См. эту ссылку для получения более подробной информации:

Ответ 3

Это зависит от того, кому нужно обработать событие. Если это родительский компонент, вы можете использовать привязки выходных событий:

@Output authenticationChange: EventEmitter<Boolean> = new EventEmitter();
checkAuthentication(){
     this._authService.getAuthentication()
     .subscribe(value => 
           if(value != this.authenticated) {
               this.authenticated = value);
               this.authenticationChange.emit(value);
      });
 }

И в вашем родительском компоненте:

 <directive (authenticationChange)="doSomething()">

Ответ 4

Я использовал {{ showValue() }} в шаблоне компонента, а в файле .ts я назвал служебную переменную

showValue() {
   this.authenticated = this._authService.authenticated;
   return "dummy"
} 

Благодаря Angular2 двустороннему привязке GUI, он работает.