2017-07-27 5 views
0

タイトルが私の意図と一致しない場合は申し訳ありません。私は何をしたいのかを説明しようと考えています。おそらく誰かがより良い代替案を教えてくれるでしょう:Angular 4の "Global"サービス(API呼び出しを保存する)

データベースからデータを取得し、これ以上APIを呼び出すことはできません。たとえば、サービスでオブジェクトの詳細を取得したいとします。サービスへの最初の呼び出しでは、APIを介してデータを取得し、内部に格納する必要があります。したがって、他のコンポーネントからサービスを再度呼び出すと、APIへの呼び出しは行われませんが、保存されたデータが返され、APIコールの必要性が大幅に軽減されます。これは可能ですか?

私はこれを試してみましたが、それは動作しません、それは常にAPIへの呼び出します:

(EDITED:フルサービスのクラスコード)を

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を学んでいますので、完全に理解できないことがあります)。

EDITED: 私は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

AppComponentではなくAppModuleのプロバイダ配列で** **のみを提供してみてください。また、遅延ロードされたモジュールもありますか? – echonax

+0

サービスクラスをもっと書くことができますか? * *と* *どのように*あなたはそれを使用していますか? – distante

答えて

0

あなたのAppModuleのプロバイダにAPIサービスを追加します。

最も簡単なキャッシングは、APIルートを保存し、paramsとレスポンスを(例えばReplaySubjectに)要求し、以前に実行したリクエストのレスポンスを返すことです。

APIがGraphqlで書かれている場合は、APIキャッシングを含むApolloをお勧めします。

+0

こんにちは!ご回答有難うございます。 ReplaySubjectを使用するキャッシングメソッドに興味がありますが、学習するための良いリソースが見つかりません。私に1つお勧めできますか?乾杯、 – Fel

0

コードを二重チェックすると、いくつかのテストを行うために兄弟コンポーネントにサービスを提供したことがわかりました。後で削除するのを忘れてしまったので、Angularはサービスの新しいインスタンスを作成しました。頑張って!

したがって、ObjectServiceをAppCömponent(またはAppModule)にのみ提供すると、完全に機能します。

ごめんなさい:

関連する問題