如何在Angular2单击函数中使用带有异步管道的Observable

Hug*_*Hou 6 observable ionic2 angularfire2 angular

情况:我正在使用FirebaseObjectObservable来填充我的Ionic 2(rc0)模板.模板代码:

 <p>{{(course | async)?.description}}</p>
 <button ion-button dark full large (click)="openDeckOnBrowser(course.deckUrl)">
  <ion-icon name='cloud-download'></ion-icon>
  <div>View Deck</div>
 </button>
Run Code Online (Sandbox Code Playgroud)

TS文件是

  this.course = this.af.database.object('/bbwLocations/courses/' + courseId); 
Run Code Online (Sandbox Code Playgroud)

this.course是Firebase Object Observable.问题是,这部分不起作用:( click)="openDeckOnBrowser(course.deckUrl).由于course.deckUrl为空.我无法将值传递给函数.

到目前为止,我发现只能使用hacky方式:

 <button id="{{(course | async)?.deckUrl}}" ion-button dark full large (click)="openDeckOnBrowser($event)">
  <ion-icon name='cloud-download'></ion-icon>
  <div id="{{(course | async)?.deckUrl}}">View Deck</div>
</button>
Run Code Online (Sandbox Code Playgroud)

并在点击事件:

  openDeckOnBrowser(event):void {
    console.log(event);
    let target = event.target || event.srcElement || event.currentTarget;
    let idAttr = target.attributes.id;
    let url = idAttr.nodeValue;
    console.log (url);
   }
Run Code Online (Sandbox Code Playgroud)

但任何官方和更容易的方法来解决这个问题?

Fab*_*ler 7

(click)="openDeckOnBrowser(course.deckUrl)"解析模板后立即评估模板.您不在此处使用异步管道,因此它deckUrl是空的.您可以通过添加第二个异步管道来解决此问题:

<p>{{(course|async)?.description}}</p>
<button ... (click)="openDeckOnBrowser((course|async).deckUrl)">...</button>
Run Code Online (Sandbox Code Playgroud)

但是,这并不好,因为将创建两个订阅.

一个(更好的)替代方案:

AsyncPipe上的官方文档始终用于*ngFor输出项目列表,而不是*ngIf输出单个项目.原因很简单:该*ngIf指令不允许任何分配.但我们可以解决这个限制:

该模板如下所示:

<div *ngFor="let course of course$|async">
    <p>Course: {{course?.name}}</p>
    <p>Url: {{course?.url}}</p>
</div>
Run Code Online (Sandbox Code Playgroud)

在组件中,我们只是将课程映射到单个课程的列表:

this.getCourse().map(c=>[c]);
Run Code Online (Sandbox Code Playgroud)

参见Plunker的工作演示


JB *_*zet 0

只需在代码中订阅可观察的内容,并将课程本身存储在组件中:

this.af.database.object('/bbwLocations/courses/' + courseId)
    .subscribe(course => this.course = course); 
Run Code Online (Sandbox Code Playgroud)

那么在你看来:

<p>{{ course?.description }}</p>
<button ion-button dark full large (click)="openDeckOnBrowser(course?.deckUrl)">
Run Code Online (Sandbox Code Playgroud)

(尽管我可能会使用 ng-if 并且仅在课程可用时显示描述和按钮)