[英]Using an array from Observable Object with ngFor and Async Pipe Angular 2
I am trying to understand how to use Observables in Angular 2. I have this service:我试图了解如何在 Angular 2 中使用 Observables。我有这个服务:
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));
}
}
This BehaviorSubject is pushed new values as so from another service:这个 BehaviorSubject 是从另一个服务推送新值的:
that._appointmentChoiceStore._appointmentChoices.next(parseObject)
I subscribe to it in the form of an observable in the component I want to display it in:我在组件中以可观察的形式订阅它,我想在其中显示它:
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
})
}
}
And the attempt to display in the view as so:并尝试在视图中显示如下:
<li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
<div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}
However, availabilities isn't yet a property of the observable object so it errors out, even though I define it in the availabilities interface as so:但是,可用性还不是 observable 对象的属性,因此它会出错,即使我在可用性界面中将其定义如下:
export interface Availabilities {
"availabilities": string[],
"length": number
}
How can I display an array asynchronously from an observable object with the async pipe and *ngFor?如何使用异步管道和 *ngFor 从可观察对象异步显示数组? The error message I get is:
我得到的错误信息是:
browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined
Here's an example这是一个例子
// 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>
Who ever also stumbles over this post.谁也曾因这篇文章而跌跌撞撞。
I belive is the correct way:我相信是正确的方法:
<div *ngFor="let appointment of (_nextFourAppointments | async).availabilities;">
<div>{{ appointment }}</div>
</div>
I think what ur looking for is this我想你要找的是这个
<article *ngFor="let news of (news$ | async)?.articles">
<h4 class="head">{{news.title}}</h4>
<div class="desc"> {{news.description}}</div>
<footer>
{{news.author}}
</footer>
If you don't have an array but you are trying to use your observable like an array even though it's a stream of objects, this won't work natively.如果您没有数组,但您尝试将 observable 用作数组,即使它是对象流,这在本机上是行不通的。 I show how to fix this below assuming you only care about adding objects to the observable, not deleting them.
我将在下面展示如何解决这个问题,假设您只关心向 observable 添加对象,而不是删除它们。
If you are trying to use an observable whose source is of type BehaviorSubject, change it to ReplaySubject then in your component subscribe to it like this:如果您尝试使用源类型为 BehaviorSubject 的 observable,请将其更改为 ReplaySubject,然后在您的组件中像这样订阅它:
this.messages$ = this.chatService.messages$.pipe(scan((acc, val) => [...acc, val], []));
<div class="message-list" *ngFor="let item of messages$ | async">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.