我正在尝试使用hateoas实现创建通用DataService
。
有一个REST api /root
,它提供了所有hateoas链接。
例如,
{
_links : {
login : {
href : '/login',
method : 'POST'
},
orders : {
href : '/orders',
method : 'GET'
},
orderById : {
href : '/order/{id}',
method : 'GET'
}
.......
}
}
在应用程序加载时,DataService
应调用/root
api并将响应存储在实例变量中,例如rootLinks
。它应该适用于整个会话。
然后DataService
应该提供followLinkByName
方法,从可用的href
获取rootLinks
并触发新的http请求。
const rootUrl: string = '/root';
const baseUrl: string = 'http://localhost:8080';
@Injectable()
export class DataService {
private observable$: Observable<any>;
private rootLinks: any;
constructor(private http: Http) {
this.ngOnInit();
}
ngOnInit() {
this.getRootLinks().subscribe();
}
private getRootLinks() {
if (this.rootLinks) {
return Observable.of(this.rootLinks);
} else if (this.observable$) {
return this.observable$;
} else {
this.observable$ = this.http.get(rootUrl).map(this.extractRootLinkData);
return this.observable$;
}
}
private extractRootLinkData(response: Response) {
this.observable$ = null; // LINE 1
let data = response.json();
this.rootLinks = data._links;
}
private extractData(response: Response) {
let body = response.json();
return body;
}
followLinkByName(linkName: String): Observable<any> {
let link;
if (this.observable$) { // LINE 2
return this.observable$.map((res) => {
link = res._links[linkName];
// make a http request and return the response
});
} else {
link = this.rootLinks[options.linkName];
options.link = link;
// make a http request and return the response
}
}
}
我在DataService
个提供程序数组中添加了此core module's
,
并core module
已导入app module
。
现在来自LoginComponent
模块的pages
使用此DataService
登录。虽然在第1行中,observable$
被指定为null,但是当从LoginComponent
进行调用时,它在第2行可用。
答案 0 :(得分:2)
由于this.http.get(rootUrl)
来电是异步的,因此您确定在使用this
时不会丢失.map(this.extractRootLinkData)
上下文?
我认为当extractRootLinkData()
方法被调用为map()
的回调时,this
上下文等于window
。因此,您在this.observable$ = null
上执行的语句window
无论如何都不存在。
您可以改为使用匿名函数:
this.observable$ = this.http.get(rootUrl).map(response => this.extractRootLinkData(response));
...或绑定this
上下文:
this.observable$ = this.http.get(rootUrl).map(this.extractRootLinkData.bind(this));
另见:How to access the correct `this` context inside a callback?