2017-07-27 85 views
0

很抱歉,如果标题不匹配我的意思。我会尽力解释我想要做什么,也许有人能告诉我一个更好的选择:“全球”的服务(保存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一些文档,但我无法弄清楚如何使用他们我需要什么?能任何人都推荐一本好的教程或书籍?

我该怎么做?在此先感谢,

+0

尝试提供它仅** **在你的AppModule的供应商阵列,而不是AppComponent。你也有任何懒惰加载模块? – echonax

+0

你可以写更多的服务类吗?和*哪里*和*你怎么使用它? – distante

回答

0

添加您的API服务,让您的AppModule的供应商。

最简单的高速缓存是节省API路线,请求参数和响应(例如在一个ReplaySubject),并返回先前执行的请求的回应。

如果你的API是写在Graphql,我建议阿波罗,其中包括API缓存。

+0

嗨!感谢您的回答。我对你提到的使用ReplaySubject的缓存方法很感兴趣,但是我找不到任何好的资源来学习。你能推荐我吗?干杯, – Fel

0

双重检查代码,我意识到我已经在一个兄弟组件中提供了服务来做一些测试,并且我忘了随后将它删除,所以Angular创建了一个新的服务实例,这就是数据不可用的原因,坚持不懈!

因此,在AppCömponent(或上文AppModule)提供ObjectService只有一次,它完美的作品。

抱歉的推移:)