“全球”的服务(保存API调用)
很抱歉,如果标题不匹配我的意思。我会尽力解释我想要做什么,也许有人能告诉我一个更好的选择:“全球”的服务(保存API调用)
我希望创建一个从数据库,并将其存储在内部,因此并不需要获取数据的服务再次调用API。例如,我希望服务获取某些对象的详细信息;对服务的第一次调用必须通过API获取数据,并将其存储在内部。因此,当我再次从其他组件调用服务时,它不会调用API,但会返回存储的数据,大大减少了对API调用的需求。这可能吗?
我试过,但它不工作,它总是让到API的调用:
(编辑:FULL服务类CODE)
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,但我认为这并不意味着它对所有组件都是“全局的”......(我仍然在学习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一些文档,但我无法弄清楚如何使用他们我需要什么?能任何人都推荐一本好的教程或书籍?
我该怎么做?在此先感谢,
添加您的API服务,让您的AppModule的供应商。
最简单的高速缓存是节省API路线,请求参数和响应(例如在一个ReplaySubject),并返回先前执行的请求的回应。
如果你的API是写在Graphql,我建议阿波罗,其中包括API缓存。
嗨!感谢您的回答。我对你提到的使用ReplaySubject的缓存方法很感兴趣,但是我找不到任何好的资源来学习。你能推荐我吗?干杯, – Fel
双重检查代码,我意识到我已经在一个兄弟组件中提供了服务来做一些测试,并且我忘了随后将它删除,所以Angular创建了一个新的服务实例,这就是数据不可用的原因,坚持不懈!
因此,在AppCömponent(或上文AppModule)提供ObjectService只有一次,它完美的作品。
抱歉的推移:)
尝试提供它仅** **在你的AppModule的供应商阵列,而不是AppComponent。你也有任何懒惰加载模块? – echonax
你可以写更多的服务类吗?和*哪里*和*你怎么使用它? – distante