Javascript 存储来自服务api调用的响应
我尝试使用以下代码将http服务包装到angular 2中:Javascript 存储来自服务api调用的响应,javascript,angular,angular2-services,Javascript,Angular,Angular2 Services,我尝试使用以下代码将http服务包装到angular 2中: @Injectable() export class HttpSuperService { private baseUrl: string; constructor(private http: Http) { } get(url: string): Observable<string> { return ( this.baseUrl ?
@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());
});
}
}
@Injectable()
导出类HttpSuperService{
私有baseUrl:string;
构造函数(专用http:http){
}
get(url:string):可观察{
返回(
这个.baseUrl?
可观察的(this.baseUrl):
this.http.get('/config/').map((res:Response)=>res)
)
.flatMap((res:any)=>{
this.baseUrl=res.\u body;
返回this.http.get(this.baseUrl+url)
.map((res2:Response)=>res2.json());
});
}
}
我试图做的是发出第一个请求来获取应用程序的baseUrl(API位于另一个URL上),但只发出一次请求(第一次)
它在第一个请求上工作,但第二个请求(即当另一个组件使用相同的服务时)不工作,因为“Observable.of”有问题。我知道我需要以某种方式使用响应,而不是字符串……这让我开始考虑这种方法。有更好的方法吗
此解决方案可行,但感觉有点冗长,因为我还计划向此服务添加其他方法(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());
});
}
}
@Injectable()
导出类HttpSuperService{
私有baseUrl:string;
构造函数(专用http:http){
}
get(url:string):可观察{
if(this.baseUrl){
返回this.http.get(this.baseUrl+url).map((res2:Response)=>res2.json());
}
返回此.http.get('/config/').map((res:Response)=>res)
.flatMap((res:any)=>{
this.baseUrl=res.\u body;
返回this.http.get(this.baseUrl+url).map((res2:Response)=>res2.json());
});
}
}
我一直使用这种方法,对我来说效果很好,我希望它有用:
在我的服务文件中:
getSomething(){
return this._http.get('YOUR-API-ENDPOINT').map(res=> res.json());
}
在我的组件中,我使用它来订阅可观察的
return this._myServiceName.getSomething().subscribe(data =>{
this.muyData=data;
}
您可以将对API url检索的依赖性分解为专用方法。该方法还可以处理一些中间步骤,如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());
}
}
从'@angular/Http'导入{Http};
从“@angular/core”导入{Inject};
从“rxjs/Observable”导入{Observable};
导入'rxjs/add/operator/mergeMap';
导入“rxjs/add/observable/fromPromise”;
导入'rxjs/add/operator/map';
导入'rxjs/add/operator/mapTo';
导入'rxjs/add/operator/do';
让baseUrl:string;
@注入导出类HttpSuperService{
routeUrl(url:string){
返回baseUrl
可观察的(基本url+url)
:this.http.get(“/config/”)
.do(response=>baseUrl=response.text())
.mapTo(baseUrl+url);
}
构造函数(只读http:http){}
get(url:string):可观察{
返回此.routeUrl(url)
.flatMap(this.http.get)
.map(res=>res.json());
}
post(url:string,body:Something):可观察{
返回此.routeUrl(url)
.flatMap(url=>this.http.post(url,body))
.map(response=>response.json());
}
}
我认为这是合理的,但我们可以做得更好,我们可以更干燥(没有太干燥的事情:):
@注入导出类HttpSuperService{
构造函数(只读http:http){}
routeUrl(url:string){
返回baseUrl
可观察的(基本url+url)
:this.http.get(“/config/”)
.do(response=>baseUrl=response.text())
.mapTo(baseUrl+url);
}
请求(url:string,makeRequest:(url:string,body?:{})=>可观察){
返回此.routeUrl(url)
.flatMap(url=>makeRequest(url))
.map(response=>response.json());
}
get(url:string):可观察{
返回this.request(url,fullUrl=>this.http.get(fullUrl));
}
post(url:string,body:Something):可观察{
返回this.request(url,fullUrl=>this.http.post(fullUrl,body));
}
}
我对URL处理并不完全满意,我可能会对其进行进一步重构,但我们已经显著减少了重复。是的,这会起作用,但这不是我真正想要做的。嗨!谢谢你的评论,我删除了我的答案,以避免给别人提供不好的信息。但是,如果您可以或有时间的话,您能更好地向我解释一下“不要将未绑定实例方法传递给回调”是什么意思吗?@SrAxi如果有人更改回调,使其使用
此
,程序将在没有警告的情况下中断。因此,如果将方法作为参数传递,则必须首先绑定它setTimeout(this.method.bind(this))
,但要使用箭头函数setTimeout(()=>this.method())代码>。签出这个答案非常感谢!我会看一看并检查我的代码。;)
@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));
}
}