Próbuję zrozumieć, jak używać Observables w Angular 2. Mam tę usługę:
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));
}
}
To BehaviorSubject jest wypychane nowe wartości z innej usługi:
that._appointmentChoiceStore._appointmentChoices.next(parseObject)
Subskrybuję go w postaci obserwowalnego w komponencie, w którym chcę go wyświetlić:
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
})
}
}
I próba wyświetlenia w widoku tak:
<li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
<div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}
Jednak dostępność nie jest jeszcze właściwością obserwowalnego obiektu, więc popełnia błędy, nawet myślałem, że zdefiniowałem to w interfejsie dostępności tak:
export interface Availabilities {
"availabilities": string[],
"length": number
}
Jak mogę wyświetlić tablicę asynchronicznie z obserwowalnego obiektu za pomocą potoku asynchronicznego i * ngFor? Otrzymuję komunikat o błędzie:
browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined
typescript
angular
rxjs
observable
C. Kearns
źródło
źródło
*ngFor="let appointment of _nextFourAppointments.availabilities | async">
availabilties
, że powinno byćavailabilities
Odpowiedzi:
Oto przykład
// in the service getVehicles(){ return Observable.interval(2200).map(i=> [{name: 'car 1'},{name: 'car 2'}]) } // in the controller vehicles: Observable<Array<any>> ngOnInit() { this.vehicles = this._vehicleService.getVehicles(); } // in template <div *ngFor='let vehicle of vehicles | async'> {{vehicle.name}} </div>
źródło
public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return this._appointmentChoices.map(object=>object.availabilities).subscribe() }
w kontrolerze, gdy ustawię go na równą, pojawia się błąd:browser_adapter.js:77Error: Invalid argument '[object Object]' for pipe 'AsyncPipe'
jak zmienić temat w obserwowalny?public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return (this._appointmentChoices.map(object=>object.availabilities).asObservable()) } }
to daje mi błąd:property asObservable does not exist on type observable
ale _appointmentChoices toSubject
?Kto kiedykolwiek potyka się o ten post.
Wierzę, że to właściwy sposób:
<div *ngFor="let appointment of (_nextFourAppointments | async).availabilities;"> <div>{{ appointment }}</div> </div>
źródło
Myślę, że szukasz tego
<article *ngFor="let news of (news$ | async)?.articles"> <h4 class="head">{{news.title}}</h4> <div class="desc"> {{news.description}}</div> <footer> {{news.author}} </footer>
źródło
Jeśli nie masz tablicy, ale próbujesz użyć tego, co jest obserwowalne, jak tablicy, nawet jeśli jest to strumień obiektów, nie zadziała to natywnie. Poniżej pokazuję, jak to naprawić, zakładając, że zależy Ci tylko na dodawaniu obiektów do obserwowalnych, a nie na ich usuwaniu.
Jeśli próbujesz użyć obserwowalnego, którego źródło jest typu BehaviorSubject, zmień je na ReplaySubject, a następnie w swoim komponencie zasubskrybuj go w następujący sposób:
Składnik
this.messages$ = this.chatService.messages$.pipe(scan((acc, val) => [...acc, val], []));
HTML
<div class="message-list" *ngFor="let item of messages$ | async">
źródło
scan
operatora możesz użyć.pipe(toArray())
Subject
jest brak dzwonieniacomplete()
. Akumulator nigdy nie działa.