我尝试使用以下代码将http服务包装在角度2中:
@Injectable()
export class HttpSuperService {
private baseUrl: string;
constructor(private http: Http) {
}
get(url: string): Observable<string> {
return (
this.baseUrl ?
Observable.of(this.baseUrl) :
this.http.get('/config/').map((res: Response) => res)
)
.flatMap((res: any) => {
this.baseUrl = res._body;
return this.http.get(this.baseUrl + url)
.map((res2: Response) => res2.json());
});
}
}
我尝试做的是第一次请求获取应用程序的baseUrl(API在另一个URL上),但只发出一次请求(第一次)。
它适用于第一个请求,但第二个请求(当另一个组件使用相同的服务时,IE)不起作用,因为&#34; Observable.of&#34;出现了问题。我知道我需要以某种方式使用Response而不是字符串......这让我开始考虑这种方法。有更好的方法吗?
这个解决方案有效但感觉有点冗长,因为我打算在此服务中添加其他方法(POST,PUT):
@Injectable()
export class HttpSuperService {
private baseUrl: string;
constructor(private http: Http) {
}
get(url: string): Observable<string> {
if (this.baseUrl) {
return this.http.get(this.baseUrl + url).map((res2: Response) => res2.json());
}
return this.http.get('/config/').map((res: Response) => res)
.flatMap((res: any) => {
this.baseUrl = res._body;
return this.http.get(this.baseUrl + url).map((res2: Response) => res2.json());
});
}
}
答案 0 :(得分:0)
您可以将对API网址检索的依赖性分解为专用方法。该方法还可以处理一些中间步骤,例如url连接,以进一步减少重复。
例如:
import {Http} from '@angular/http';
import {Inject} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mapTo';
import 'rxjs/add/operator/do';
let baseUrl: string;
@Inject export class HttpSuperService {
routeUrl(url: string) {
return baseUrl
? Observable.of(baseUrl + url)
: this.http.get('/config/')
.do(response => baseUrl = response.text())
.mapTo(baseUrl + url);
}
constructor(readonly http: Http) {}
get(url: string): Observable<string> {
return this.routeUrl(url)
.flatMap(this.http.get)
.map(res => res.json());
}
post(url: string, body: Something): Observable<Something> {
return this.routeUrl(url)
.flatMap(url => this.http.post(url, body))
.map(response => <Something>response.json());
}
}
我认为这是合理的,但我们可以做得更好,我们可以更干(没有太干的事情)):
@Inject export class HttpSuperService {
constructor(readonly http: Http) {}
routeUrl(url: string) {
return baseUrl
? Observable.of(baseUrl + url)
: this.http.get('/config/')
.do(response => baseUrl = response.text())
.mapTo(baseUrl + url);
}
request<R>(url: string, makeRequest: (url: string, body?: {}) => Observable<Response>) {
return this.routeUrl(url)
.flatMap(url => makeRequest(url))
.map(response => <R>response.json());
}
get(url: string): Observable<string> {
return this.request<string>(url, fullUrl => this.http.get(fullUrl));
}
post(url: string, body: Something): Observable<Something> {
return this.request<Something>(url, fullUrl => this.http.post(fullUrl, body));
}
}
我对URL处理并不完全满意,我可能会进一步重构它,但我们已经大大减少了重复。
答案 1 :(得分:-1)
我总是使用这种方法,对我来说很好,我希望它有用:
在我的服务文件中:
getSomething(){
return this._http.get('YOUR-API-ENDPOINT').map(res=> res.json());
}
在我的组件中我使用它来订阅Observable
return this._myServiceName.getSomething().subscribe(data =>{
this.muyData=data;
}