模板中带有异步管道的 Observable 不适用于单个值

use*_*188 3 rxjs rxjs5 angular

我有一个组件向我的服务请求一个 Observable 对象(也就是说,底层的 http.get 返回一个对象)。

该对象(可观察的)与我的模板中的异步管道结合使用。不幸的是,我收到一个错误:

无法读取 null 的属性“姓氏”

我一直在为这件事伤透脑筋。类似类型的代码可以在对象列表上正确运行(与 *ngFor 结合使用)。

<li>{{(person | async)?.lastname}}</li>
Run Code Online (Sandbox Code Playgroud)

我的服务中的方法:

getPerson(id: string): Observable<Person> {        
   let url = this.personsUrl + "/" + id;
   return this.http.get(url, {headers: new Headers({'Accept':'application/json'})})
              .map(r => r.json())
              .catch(this.handleError); //error handler
}
Run Code Online (Sandbox Code Playgroud)

在我的组件中:

//... imports omitted

@Component({
  moduleId: module.id,
  selector: 'app-details-person',
  templateUrl: 'details-person.component.html',
  styleUrls: ['details-person.component.css'],
})
export class DetailsPersonComponent implements OnInit, OnDestroy 
{
   person: Observable<Person>;
   sub: Subscription;

   constructor(private personService: PersonService, private route: ActivatedRoute) {
   }

  ngOnInit() {
     this.sub = this.route.params.subscribe(params => {
                 let persId = params['id'];
                 this.person = this.personService.getPerson(persId);
                });
  }

  ngOnDestroy(): void {
     this.sub.unsubscribe();
  }
}

Run Code Online (Sandbox Code Playgroud)

显然,可观察的是/返回管道中的空对象值。我已经检查过我是否真的从我的服务中获得了一个非空的 Observable,并且我可以确认存在从我的服务返回的(底层)对象。

当然,在从服务中检索 Observable 后,我可以在组件中订阅 Observable,但我真的很想使用异步构造。

顺便说一句,另一个问题:是否已经有一种关于如何处理异步管道中发生的错误的模式?(使用异步管道的缺点......错误会延迟到视图的渲染时间。

Sim*_*ver 5

如果您使用Subject<T>observable 而不是ReplaySubject<T>or ,则可能会发生这种情况BehaviorSubject<T>

a 发生的情况是,它仅向当时Subject<T>注册的任何侦听器“广播”其值一次。

因此,如果您调用next('hello word')可观察的对象,message: Subject<string>它只能更新 UI(如果该“部分”的 UI 在该时刻存在)。

因此,在此示例中,该消息不会出现 - 除非您拨打next两次!

<div *ngIf="message | async">
   here is the message {{ message | async }}
</div>
Run Code Online (Sandbox Code Playgroud)

最简单的解决方案是使用ReplaySubject<string>(1)where1是它记住的值的数量(我们这里只需要一个)。