Rxjs Subject.asObservable() не работает, но работает BehaviorSubjectпочему?

Я проверил это https://github.com/angular/angular/issues/12129 но я не вижу никакого решения...

Angular 2.0.1 AsyncPipe не работает с Rx Subject .

Решение здесь состоит в том, чтобы создать наблюдаемую переменную в компоненте

Который у меня есть, но все еще не работает... не уверен, почему он не работает, если я переключаю Subject в моем UserStateService на BehaviorSubject, все работает...

Примечание. И UserDataService, и UsersStateService предоставляются в корне app.module.ts.

user-data.service.ts -> сделать http-запрос, который я вызываю в своем компоненте

fetchUsers():void{
   this.httpClient.get<User[]>(this.apiUrl, {
  observe: 'body',
  responseType: 'json'
})
.subscribe( (response: User[])=>{
    this.usersStateService.setUsersList(response);  <-- set to local state service

  });

}

пользователи-state.service.ts

userListState = new Subject<User[]>();   <-- Change this to BehaviorSubject<User[]>([])  everything works!

setUsersList(users: User[]):void {
  this.userListState.next(users.slice());
}

getUsersListState():Observable<User[]>{
   return this.userListState.asObservable();
}

компонент.ts

 users: Observable<User[]>;

 ngOnInit() {

 if(this.usersStateService.hasUserList()){

  this.users = this.usersStateService.getUsersListState();  -|
                                                             |
  // this.usersStateService.getUsersListState()              |
  //   .subscribe((x) => console.log(x));                   -| <-- This does not output for some reason IF Subject... BehaviorSubject works..
}else{
  console.log("No data in local stat -> fetch") . <-- This works either with Subject or BehaviorSubject
  this.userData.fetchUsers();
  this.users = this.usersStateService.getUsersListState();
}

}

HTML

<li *ngFor="let u of (users | async)">u.name</li>

Пожалуйста, любые идеи будут отличными, спасибо!


person Eric Huang    schedule 27.06.2018    source источник
comment
Субъект уже является наблюдаемым, вы можете просто указать на него. В вашем компоненте вы можете просто сделать this.users = this.usersStateService.userListState;   -  person Deepak Sharma    schedule 27.06.2018
comment
stackoverflow.com/ вопросы/43348463/   -  person Vikas    schedule 27.06.2018
comment
@Vikas спасибо за ссылку, это очень помогает   -  person Eric Huang    schedule 28.06.2018


Ответы (1)


Субъект не содержит никаких данных, он просто вызывает все, что подписывается на него со значением. BehaviorSubject содержит данные, и каждый раз, когда вы вызываете emit, он заменяет текущие данные.

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

this.usersStateService.getUsersListState()              
 .subscribe((x) => console.log(x));  ==> would be empty 

С BehaviorSubject он содержит последние данные, а также может быть инициализирован значениями.

let _array = ['one','two']
let bs = new BehaviorSubject<any>(_array ).asObservable();
bs.subscribe(arr => {
 console.log(arr) // ==> Would log the _array: ['one','two']
})

Итак, в вашем случае, когда вы пытаетесь получить данные через Subject, он просто не существует после первого вызова (когда вы испускаете), в то время как BehaviorSubject сохраняет ваше начальное значение и каждый раз, когда вы испускаете, поэтому всегда есть постоянные данные.
**Если вам нужно каждый раз более одного значения, вам следует изучить ReplySubject.

person dAxx_    schedule 27.06.2018
comment
Не могли бы вы предоставить какой-нибудь код, чтобы продемонстрировать, что вы имеете в виду? Я думаю, это сделает ваш ответ более полным... Я отмечу как ответ, как только вы его обновите. - person Eric Huang; 28.06.2018
comment
Я обновил с более подробной информацией, я надеюсь, что теперь это лучше. удачи - person dAxx_; 28.06.2018
comment
Спасибо за обновление... Для других также проверьте ссылку Vikas в комментариях. - person Eric Huang; 29.06.2018