2017-07-27 63 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只有一次,它完美的作品。

抱歉的推移:)