observables - Cómo utilizar Observable con tubo Async dentro de la función de clic Angular2
observables angular 5 (2)
En su plantilla (click)="openDeckOnBrowser(course.deckUrl)"
se evalúa tan pronto como se analiza la plantilla. Usted no usa la tubería asíncrona aquí, por lo tanto, el deckUrl
está vacío. Puede solucionar esto agregando una segunda tubería asíncrona:
<p>{{(course|async)?.description}}</p>
<button ... (click)="openDeckOnBrowser((course|async).deckUrl)">...</button>
Sin embargo, esto no es bueno ya que se crearán dos suscripciones.
Una (mejor) alternativa:
Los documentos oficiales en el AsyncPipe siempre usan *ngFor
para generar una lista de elementos y no *ngIf
para generar un solo elemento. La razón es simple: la directiva *ngIf
no permite ninguna asignación. Pero podemos evitar esta limitación:
La plantilla se ve de la siguiente manera:
<div *ngFor="let course of course$|async">
<p>Course: {{course?.name}}</p>
<p>Url: {{course?.url}}</p>
</div>
Y en el componente, asignaremos el curso a una lista de un solo curso:
this.getCourse().map(c=>[c]);
Situación: estoy usando FirebaseObjectObservable para completar mi plantilla Ionic 2 (rc0). Código de la plantilla:
<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>
El archivo TS es
this.course = this.af.database.object(''/bbwLocations/courses/'' + courseId);
this.course es un Objeto de Firebase Observable. El problema es que esta parte no funcionará: (click) = "openDeckOnBrowser (course.deckUrl). Como el course.deckUrl está vacío. No puedo pasar el valor a la función.
La única forma de hacky que encontré para trabajar hasta ahora es esta:
<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>
Y en el evento click:
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);
}
¿Pero alguna forma oficial y más fácil de abordar esto?
Simplemente suscríbase a lo observable en su código y almacene el curso en el componente:
this.af.database.object(''/bbwLocations/courses/'' + courseId)
.subscribe(course => this.course = course);
Entonces en tu vista:
<p>{{ course?.description }}</p>
<button ion-button dark full large (click)="openDeckOnBrowser(course?.deckUrl)">
(aunque probablemente usaría ng-si y solo mostraría la descripción y el botón una vez que el curso esté disponible)