共享时的角度可观察行为奇数

时间:2018-07-13 14:40:09

标签: angular rxjs ngrx

我可以观察到,当我使用rxjs的“ share”运算符时,在Angular模板中的行为会很奇怪。这是我在服务中设置两个可观察对象的方法:

this.family = this.store.select(getFamily).pipe(
  tap(family => {
    if (family == null) {
      this.loadFamily();
    }
  }),
  filter(family => family != null),
  share(),
);
this.familyMembers = this.family.pipe(
  map(family => {
    return family.familyMembers;
  })
);

然后我将可观察到的familyMember作为属性添加到我的组件中

this.familyMembers = this.familyService.familyMembers

我的标记看起来像这样:

 <tbody *ngIf="(familyMembers | async) != null">
        <pre> {{(familyMembers | async) | json}}</pre>

现在奇怪的是,当填充familyMembers(两个数组)时,即使在我使用<pre>检查是否为null的情况下,null仍将使用*ngIf进行渲染。

我还有一个列表,其中没有任何内容,如下所示:

<ng-template ngFor let-familyMember let-i="index" [ngForOf]="(familyMembers | async)" [ngForTrackBy]="trackByFn">

我知道发出的最后familyMembers是正确的两个家庭成员,我已经用mapconsole.log进行了检查。 Angular模板似乎将其视为null ..但不是吗?

如果我从可观察的家庭中删除share(),但tap()运行两次,则一切正常。

编辑:

使用shareReplay()而不是share()解决了我的问题。当所有订阅退订时,share()不会重新发送值。

1 个答案:

答案 0 :(得分:1)

您应该使用shared()运算符,因为您两次订阅,所以才得到重复的。
您应该相应地更改html代码:

 <tbody *ngIf="familyMembers | async as familyProps">
        <pre> {{familyProps | json}}</pre> 

在第一个* ng中,如果您检查值的存在,则无需在另一行中再次使用异步管道,因为如果未通过第一个异步管道,则不会调用它。
另外,当您调用“ as familyProps”并在下一行中使用它时,请确保在执行此行时此本地对象将可用。如果没有'as',它可能会起作用,但是根据您的评论,我只是添加来确保它。

-编辑
您调用的每个异步管道也都将订阅,现在发生的是第一行带有* ngIf等待值,第二行位于此包装器内,因此它将在第一行执行之前不会调用。
现在,当第一行通过时,第二行将尝试使用异步管道进行订阅,但由于第一行订阅和shared()运算符,其已经完成。
您可以尝试一下,它也应该可以工作:

<tbody *ngIf="familyMembers | async">
  <pre> {{familyMembers | json}} </pre>