J'essaie de comprendre comment utiliser Observables dans Angular 2. J'ai ce service:
import {Injectable, EventEmitter, ViewChild} from '@angular/core';
import {Observable} from "rxjs/Observable";
import {Subject} from "rxjs/Subject";
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from './availabilities-interface'
@Injectable()
export class AppointmentChoiceStore {
public _appointmentChoices: BehaviorSubject<Availabilities> = new BehaviorSubject<Availabilities>({"availabilities": [''], "length": 0})
constructor() {}
getAppointments() {
return this.asObservable(this._appointmentChoices)
}
asObservable(subject: Subject<any>) {
return new Observable(fn => subject.subscribe(fn));
}
}
Ce BehaviorSubject reçoit de nouvelles valeurs comme tel à partir d'un autre service:
that._appointmentChoiceStore._appointmentChoices.next(parseObject)
Je m'y abonne sous forme d'observable dans le composant dans lequel je souhaite l'afficher:
import {Component, OnInit, AfterViewInit} from '@angular/core'
import {AppointmentChoiceStore} from '../shared/appointment-choice-service'
import {Observable} from 'rxjs/Observable'
import {Subject} from 'rxjs/Subject'
import {BehaviorSubject} from "rxjs/Rx";
import {Availabilities} from '../shared/availabilities-interface'
declare const moment: any
@Component({
selector: 'my-appointment-choice',
template: require('./appointmentchoice-template.html'),
styles: [require('./appointmentchoice-style.css')],
pipes: [CustomPipe]
})
export class AppointmentChoiceComponent implements OnInit, AfterViewInit {
private _nextFourAppointments: Observable<string[]>
constructor(private _appointmentChoiceStore: AppointmentChoiceStore) {
this._appointmentChoiceStore.getAppointments().subscribe(function(value) {
this._nextFourAppointments = value
})
}
}
Et la tentative d'afficher dans la vue comme suit:
<li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
<div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}
Cependant, les disponibilités ne sont pas encore une propriété de l'objet observable, donc il se trompe, même si je le définis dans l'interface des disponibilités comme suit:
export interface Availabilities {
"availabilities": string[],
"length": number
}
Comment puis-je afficher un tableau de manière asynchrone à partir d'un objet observable avec le tube asynchrone et * ngFor? Le message d'erreur que je reçois est:
browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined
typescript
angular
rxjs
observable
C. Kearns
la source
la source
*ngFor="let appointment of _nextFourAppointments.availabilities | async">
availabilties
alors qu'il devrait y avoiravailabilities
Réponses:
Voici un exemple
la source
public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return this._appointmentChoices.map(object=>object.availabilities).subscribe() }
dans le contrôleur, lorsque je le règle sur égal, j'obtiens l'erreur:,browser_adapter.js:77Error: Invalid argument '[object Object]' for pipe 'AsyncPipe'
comment transformer le sujet en observable?public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return (this._appointmentChoices.map(object=>object.availabilities).asObservable()) } }
cela me donne l'erreurproperty asObservable does not exist on type observable
:, mais _appointmentChoices est unSubject
?Qui a jamais trébuché sur ce post.
Je crois que c'est la bonne façon:
la source
Je pense que ce que tu cherches c'est ça
la source
Si vous n'avez pas de tableau mais que vous essayez d'utiliser votre observable comme un tableau même s'il s'agit d'un flux d'objets, cela ne fonctionnera pas en mode natif. Je montre comment résoudre ce problème ci-dessous en supposant que vous ne vous souciez que d'ajouter des objets à l'observable, pas de les supprimer.
Si vous essayez d'utiliser une observable dont la source est de type BehaviorSubject, changez-la en ReplaySubject puis dans votre composant abonnez-vous comme ceci:
Composant
HTML
la source
scan
opérateur, vous pouvez utiliser.pipe(toArray())
Subject
est de ne pas appelercomplete()
. L'accumulateur ne fonctionnera jamais.