使用async在同一个Angular模板中绑定到相同的observable两次

时间:2018-03-16 19:04:10

标签: angular

我在Component的模板中有以下内容:

<span>
  {{(userService.CurrentUser | async)?.FullName }}
</span>

userService.CurrentUser是一个Observable,它生成User类型的对象。用户有名为FirstName,LastName,FullName等的名称

此代码可以正常工作。我现在正尝试自定义在不同屏幕尺寸下显示的内容。我按如下方式修改了模板:

<!--  At screen size sm , show the user's first name  -->
<span class="d-none d-sm-inline d-md-none">
  {{(userService.CurrentUser | async)?.FirstName }}
</span>

<!--  At screen size md or larger, display user's full name  -->
<span class="d-none d-md-inline">
  {{(userService.CurrentUser | async)?.FullName }}
</span>

不幸的是,这并没有像预期的那样奏效。一点点实验似乎表明两者中的任何一个&lt; span&gt;元素在模板中排在第一位,标记将对其表达式进行评估,而第二个元素则不会,导致它没有内容。

如果我绑定到组件中的属性而不是使用异步管道绑定到Observable,我就不会遇到这个问题。

虽然我可以通过在我的组件中订阅它并保持我自己的Observable最新值的副本来跟踪Observable的当前值,但这似乎是重写了异步管道。

我还在angular - using async pipe on observable<Object> and bind it to local variable in html中看到,我可以使用*ngIf将最新的可观察值存储到变量中。

为什么我没有按预期工作?在选择上述两种选择之一之前,我想先了解一下。

更新:以下是我使用设置CurrentUser Observable的代码。基于评论,我认为这是问题的根源。我怀疑这是因为我只跟踪传递给Observable构造函数的函数中的单个订阅者。我不认为我理解创建Observable的正确方法,然后通知Observers。

export class UserService {
  private currentUser : User;
  private currentUserObservable : Observable<User>;
  private currentUserObserver : Observer<User>;

  constructor()  {
    this.currentUserObservable = new Observable<User>(
      observer => {
        this.currentUserObserver = observer;
      }
    );
  }

  get CurrentUser() : Observable<User> {
    return this.currentUserObservable;
  }

  login (emailAddress : string, password : string) : void {
    this.currentUser = new User(emailAddress, "username", "First Name", "Last Name");      
    this.currentUserObserver.next(this.currentUser);
  }
}

1 个答案:

答案 0 :(得分:2)

它应该按原样运作。 然而,文档指出,有几个效率低下: Storing conditional result in a variable (Show a set of properties from the same object)

你可以尝试:

<ng-container *ngIf="userService.CurrentUser | async as user">

  <!--  At screen size sm , show the user's first name  -->
  <span class="d-none d-sm-inline d-md-none">
    {{ user.FirstName }}
  </span>

  <!--  At screen size md or larger, display user's full name  -->
  <span class="d-none d-md-inline">
    {{ user.FullName }}
  </span>

</ng-container>

只有一个嫌疑人,它更清洁。