Menggunakan array dari Objek Observable dengan ngFor dan Async Pipe Angular 2


93

Saya mencoba untuk memahami bagaimana menggunakan Observables di Angular 2. Saya memiliki layanan ini:

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));
    }
}

BehaviorSubject ini didorong oleh nilai-nilai baru dari layanan lain:

that._appointmentChoiceStore._appointmentChoices.next(parseObject)

Saya berlangganan dalam bentuk yang dapat diamati di komponen yang ingin saya tampilkan di:

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
        })
    }
}

Dan upaya untuk menampilkan dalam tampilan sebagai:

  <li *ngFor="#appointment of _nextFourAppointments.availabilities | async">
         <div class="text-left appointment-flex">{{appointment | date: 'EEE' | uppercase}}

Namun, ketersediaan belum menjadi properti dari objek yang dapat diamati sehingga terjadi kesalahan, bahkan saya pikir saya mendefinisikannya di antarmuka ketersediaan sebagai:

export interface Availabilities {
  "availabilities": string[],
  "length": number
}

Bagaimana cara menampilkan array secara asinkron dari objek yang dapat diamati dengan pipa asinkron dan * ngFor? Pesan kesalahan yang saya dapatkan adalah:

browser_adapter.js:77 ORIGINAL EXCEPTION: TypeError: Cannot read property 'availabilties' of undefined

Apa pesan kesalahan yang sebenarnya?
Günter Zöchbauer

diedit untuk menambah kesalahan
C. Kearns

dengan angular-rc1 terbaru sintaksnya adalah*ngFor="let appointment of _nextFourAppointments.availabilities | async">
Jagannath

ini benar, tetapi tidak menyebabkan kesalahan. itu hanya memberi peringatan.
C. Kearns

3
Saya yakin ada kesalahan ketik di suatu tempat. Kesalahan mengatakan availabiltiessementara seharusnya adaavailabilities
Ivan Sivak

Jawaban:


154

Berikut contohnya

// 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>

fungsi get saya mengembalikan subjek:, public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return this._appointmentChoices.map(object=>object.availabilities).subscribe() } di pengontrol ketika saya menyetelnya sama, saya mendapatkan kesalahan:, browser_adapter.js:77Error: Invalid argument '[object Object]' for pipe 'AsyncPipe'bagaimana cara mengubah subjek menjadi yang dapat diamati?
C. Kearns

public _appointmentChoices: Subject<any> = new Subject() getAppointments() { return (this._appointmentChoices.map(object=>object.availabilities).asObservable()) } } ini memberi saya kesalahan property asObservable does not exist on type observable:, tetapi _appointmentChoices adalah Subject?
C. Kearns

Itu sudah bisa diamati! Saya hanya perlu berlangganan!
C. Kearns

Saya memiliki masalah tambahan dengan mengintegrasikan mata pelajaran. Berikut adalah StackBlitz menggunakan observable dan subjek: stackblitz.com/edit/subject-as-observable-list-example
IceWarrior353

12

Siapa yang juga tersandung posting ini.

Saya percaya adalah cara yang benar:

  <div *ngFor="let appointment of (_nextFourAppointments | async).availabilities;"> 
    <div>{{ appointment }}</div>
  </div>

1

Saya pikir apa yang Anda cari adalah ini

<article *ngFor="let news of (news$ | async)?.articles">
<h4 class="head">{{news.title}}</h4>
<div class="desc"> {{news.description}}</div>
<footer>
    {{news.author}}
</footer>


1

Jika Anda tidak memiliki array tetapi Anda mencoba menggunakan observable Anda seperti array meskipun itu adalah aliran objek, ini tidak akan berfungsi secara native. Saya menunjukkan cara memperbaikinya di bawah ini dengan asumsi Anda hanya peduli tentang menambahkan objek ke yang dapat diamati, bukan menghapusnya.

Jika Anda mencoba menggunakan observable yang sumbernya berjenis BehaviorSubject, ubah ke ReplaySubject lalu di komponen Anda berlangganan seperti ini:

Komponen

this.messages$ = this.chatService.messages$.pipe(scan((acc, val) => [...acc, val], []));

Html

<div class="message-list" *ngFor="let item of messages$ | async">

Alih-alih scanoperator, Anda dapat menggunakan.pipe(toArray())
MotKohn

Perangkap lain saat membuat sendiri Subjectadalah tidak menelepon complete(). Akumulator tidak akan pernah bekerja.
MotKohn
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.