情况:我正在使用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>
TS文件是
this.course = this.af.database.object('/bbwLocations/courses/' + courseId);
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>
点击事件:
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);
}
但任何官方的,更简单的方法来解决这个问题?
答案 0 :(得分:7)
在模板中解析模板时,会对您的模板(click)="openDeckOnBrowser(course.deckUrl)"
进行评估。您不在此处使用异步管道,因此deckUrl
为空。您可以通过添加第二个异步管道来解决此问题:
<p>{{(course|async)?.description}}</p>
<button ... (click)="openDeckOnBrowser((course|async).deckUrl)">...</button>
然而,这并不好,因为将创建两个订阅。
A(更好)替代方案:
官方docs on the AsyncPipe始终使用*ngFor
输出项目列表,而不是*ngIf
输出单个项目。原因很简单:*ngIf
指令不允许任何分配。但我们可以解决这个限制:
模板如下所示:
<div *ngFor="let course of course$|async">
<p>Course: {{course?.name}}</p>
<p>Url: {{course?.url}}</p>
</div>
在组件中,我们只是将课程映射到单个课程列表:
this.getCourse().map(c=>[c]);
答案 1 :(得分:1)
只需订阅代码中的observable,并将课程本身存储在组件中:
this.af.database.object('/bbwLocations/courses/' + courseId)
.subscribe(course => this.course = course);
然后在你看来:
<p>{{ course?.description }}</p>
<button ion-button dark full large (click)="openDeckOnBrowser(course?.deckUrl)">
(虽然我可能会使用ng-if并且仅在课程开始时显示说明和按钮)