Angular2: 将数组转换为可观测

我有一个通过 http 获取服务数据的组件,问题是我不希望每次显示这个组件时都碰到 API 后端。我希望我的服务检查数据是否在内存中,如果在内存中,返回一个可观察的数组,如果不在内存中,发出 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');
}
}
104057 次浏览

你说得对。如果内存中已经有了数据,那么可以使用 of观察(相当于 RxJS4中的 return/just)。

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

这可能是非常晚来,但我一直在使用 sessionStorage相当严重,以处理我的一些工作。如果因为人们跳来跳去而丢失了状态,那么您仍然拥有数据。

getSubjects(): Observable < Subject[] > {
let SubjectsString = sessionStorage.getItem("Subjects");


if (SubjectsString) {
let subjects: Subject[] = JSON.parse(SubjectsString);
console.log("GETTING DATA FROM SESSION STORAGE");
return Observable.of(subjects);
} else {
let url = `${this.apiHost}/api/subject`;
return this.http.get(url)
.map(res => {
sessionStorage.setItem("Subjects", JSON.stringify(res.json()));
return res.json();
});
}
}

在这个示例中,我得到了 Subject 的一个类和 apiHost 的一个定义,但是其余部分非常简单。你打电话给服务中心。您的组件不知道数据在哪里,也不关心。该服务检查本地存储,如果有的话,将其转换为可观察的数据并返回,如果没有的话,该服务去获取它,然后将其保存到本地存储,然后返回。

在我的例子中,我有一些有数百页的巨大应用程序。用户可能会从一个不错的 Angular4页面跳转到一个经典的 ASP 年龄,并再次多次返回。将所有菜单项甚至搜索结果都保存在会话存储中是一个救命稻草。

快速解决方案:

getSomething(): Observable < Object[] > {
return new Observable(observable => {
this.http.get('example.com').subscribe(results => {
observable.next(results.json());
observable.complete();
});
});
}

有些人喜欢我的想法不同,这是从 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);

希望能帮到其他人。

import { of } from 'rxjs';
    

return of(this.contacts);

角度7就足够把 of()放进去了,不管你放进去什么 of()将被改为可观测。在这里,this.contacts被转换 到可以观察到的程度。

import { of } from 'rxjs';


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

也可以使用 Observable.of(resultArray);

import { Observable } from 'rxjs;'