如果标题与我的意思不符,请抱歉。我会尝试解释我想做的事情,也许有人可以告诉我一个更好的选择:
我想创建一个服务,从数据库中获取数据并将其存储在内部,因此不再需要调用API。例如,我希望服务获取某些对象的详细信息;对服务的第一次调用必须通过API获取数据,并将其存储在内部。因此,当我再次从其他组件调用该服务时,它不会调用API,但会返回存储的数据,从而大大减少了对API调用的需求。这可能吗?
我试过了,但它不起作用,它总是调用API:
(已编辑:完整服务类代码)
import { Injectable } from '@angular/core';
import { Http, Response, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class ObjectService {
// We'll store the objects in this array
private savedObjects : any;
private objSubject = new Subject<any>();
constructor(private http: Http) {
}
getObjects() : Observable<any> {
const url = `http://URL_TO_API/objects`;
if(!this.savedObjects || !this.savedObjects.length) {
// We don't have any saved objects yet, make API call
console.log("Getting the objects through API call");
return this.http.get(url)
.map(this.extractData) // Basically returns a JSON
.map((objs) => { this.savedObjects = objs; return objs; } )
.catch(this.handleError)
;
}
else {
// Don't need to call the API
console.log(["No API", this.savedObjects]);
this.objSubject.next(this.savedObjects);
return this.objSubject.asObservable();
}
}
private extractData(res: Response) {
//console.log("RECEIVED DATA: " + res.text());
let body = res.json();
return body || {};
}
private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
我只在AppComponent中提供服务,但我认为这并不意味着它是全球的&#39;对于所有组件......(我还在学习Angular 4,所以有些事情我不能完全理解)。
编辑: 我只在AppModule文件中提供了服务,但没有任何反应。
我从其他组件使用此服务的方式是:
(...)
import { ObjectService } from '../../services/object.service';
(...)
@Component({
selector: 'app-target-container',
templateUrl: './app-target-container.component.html',
styleUrls: ['./app-target-container.component.css'],
encapsulation: ViewEncapsulation.None,
providers: []
})
export class AppTargetContainerComponent implements OnInit {
constructor(protected objectService : ObjectService) {
}
ngOnInit() {
// Get the objects
this.objectService.getObjects().subscribe((objects: any) => {
console.log(['Read objects: ', objects]);
this.processObjects(objects);
});
}
processObjects(objects : any) {
// DO STUFF
}
}
我一直在阅读有关ReplaySubject的一些文档,但我无法弄清楚如何将它们用于我需要的内容......任何人都可以推荐一本好的教程或书籍吗?
我怎么能这样做?提前谢谢,
答案 0 :(得分:0)
将您的API服务添加到AppModule的提供者。
最简单的缓存是保存API路由,请求参数和响应(例如在ReplaySubject中)并返回先前执行的请求的响应。
如果您的API是用Graphql编写的,我建议使用包含API缓存的Apollo。
答案 1 :(得分:0)
仔细检查代码,我意识到我已经在兄弟组件中提供了服务以进行一些测试,我忘了以后删除它,所以Angular创建了一个新的服务实例,这就是数据不是的原因持久!
因此,只在AppCömponent(或AppModule)中提供ObjectService,它才能完美运行。
对失效感到抱歉:)