أنغولار - Angular2: تحويل المصفوفة إلى Observable


لدي مكون يحصل على البيانات من خدمة عبر http، المشكلة هي أنني لا أريد الوصول إلى واجهة برمجة التطبيقات الخلفية في كل مرة أعرض فيها هذا المكون. أريد من خدمتي التحقق مما إذا كانت البيانات موجودة في الذاكرة، إذا كانت موجودة، إرجاع ملاحظة observable بالمصفوفة الموجودة في الذاكرة، وإذا لم تكن موجودة، إجراء طلب http.

مكوني

import { Component, OnInit } from 'angular2/core';
import { Router } from 'angular2/router';

import { Contact } from './contact';
import { ContactService } from './contact.service';

@Component({
    selector: 'contacts',
    templateUrl: 'app/contacts/contacts.component.html'
})
export class ContactsComponent implements OnInit {

    contacts: Contact[];
    errorMessage: string;

    constructor(
        private router: Router,
        private contactService: ContactService) { }

    ngOnInit() {
        this.getContacts();
    }

    getContacts() {
        this.contactService.getContacts()
            .subscribe(
                contacts => this.contacts = contacts,
                error => this.errorMessage = <any>error
            );
    }
}

خدمتي

import { Injectable } from 'angular2/core';
import { Http, Response, Headers, RequestOptions } from 'angular2/http';
import { Contact } from './contact';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class ContactService {

    private contacts: Array<Contact> = null;

    constructor(private http: Http) {

    }

    getContacts() {
        // Check first if contacts == null
        // if not, return Observable(this.contacts)? <-- How to?

        return this.http.get(url)
            .map(res => <Contact[]>res.json())
            .do(contacts => {
                this.contacts = contacts;
                console.log(contacts);
            }) // eyeball results in the console
            .catch(this.handleError);
    }


    private handleError(error: Response) {
        // in a real world app, we may send the server to some remote logging infrastructure
        // instead of just logging it to the console
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}

الإجابة رقم 1

أنت على حق هناك. إذا كان لديك البيانات بالفعل في الذاكرة، يمكنك استخدام of observable (ما يعادل return/just في RxJS 4).

getContacts() {

    if(this.contacts != null) 
    {
        return Observable.of(this.contacts);
    } 
    else 
    {
        return this.http.get(url)
            .map(res => <Contact[]> res.json())
            .do(contacts => this.contacts = contacts)
            .catch(this.handleError);
    }
}

الإجابة رقم 2

import { of } from 'rxjs';
    
return of(this.contacts);

الإجابة رقم 3

في Angular7 يكفي فقط وضع of(). كل ما تضعه داخل of() سيُحوَّل إلى Observable. هنا، this.contacts تم تحويله إلى Observable.

import { of } from 'rxjs';

getContacts() {
    if (this.contacts != null) {
        return of(this.contacts);
    }
}

الإجابة رقم 4

بعض الأشخاص مثلي يريدون ذلك بشكل مختلف، وهو من string[] إلى Observable<string>.

هذا مثال يتضمن التحويل:

import { from } from 'rxjs/observable/from';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toArray';

const ids = ['x12', 'y81'];
let userUrls: string[];

from(ids) // Converting string[] into Observable<string>
  .map(id => 'http://localhost:8080/users/' + id)
  .toArray()
  .subscribe(urls => userUrls = urls);

نأمل أن يساعد ذلك الآخرين بعض الشيء.