サービス(データを取得)とコンポーネント(それを表示)を含むprejectがあります。
App.component.tsでコードを最小限に抑えたい。
私が持っているサービスでは:
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts', httpOptions).subscribe(
result => {
return result;
this.theData = result;
},
error => {
return error;
}
);
}
そして私のapp.component.tsで:
getPostsFromService() {
this.myService.getPosts();
}
しかし、もちろん、結果を取得してコンポーネントに渡す必要がありますが、次のようなものは機能しません。
myData;
...
getPostsFromService() {
this.myData = this.myService.getPosts();
}
だから、私の質問は、どのようにこれを行うことができますか、サービスではなくコンポーネントでsubscribeを呼び出すことを本当にお勧めですか?
新規HttpClientModuleJSONはデフォルトと想定され、res.json()
を使用して明示的に解析する必要はなくなりました
HttpClient
に応答のタイプを伝えることで、出力の消費をより簡単かつ明確にすることができます。
応答の型チェックは、typeパラメーターを使用して実行できます
インターフェースを作成する
_export interface Idata{
userId:number;
Id:number;
title:string;
body:string;
}
_
Http
はobservable
を返し、http.get<Idata[]>(...)
を使用するとresponse
をIdata型として返すように_HttpClient.get
_に伝えることができます。 _Observable<Idata[]>
_タイプの.
サービスで
_import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import {Observable} from 'rxjs';
import {Idata} from './Idata'
@Injectable()
export class ShareService {
constructor(private httpc:HttpClient)
{
}
public getPosts():Observable<Idata[]>
{
return this.httpc.get<Idata[]>('https://jsonplaceholder.typicode.com/posts');
}
}
_
コンポーネントでsubscribe
から_Observable<Idata[]>
_にIdataのインスタンスを取得します
_ public data:Array<Idata>=[];
constructor(public service:ShareService)
{
this.service.getPosts().subscribe(value => {
this.data=value;
});
}
_
別の方法として、async
パイプを使用するAsyncPipe
が引数としてobservable
またはpromise
を受け入れ、subscribe
を呼び出すか、thenハンドラをアタッチします次に、非同期の結果を待ってから呼び出し元に渡します。
_public response:Observable<Idata[]>;
constructor(public service:ShareService)
{
this.response=this.service.getPosts();
}
_
[〜#〜] html [〜#〜]
_<div *ngFor="let item of (response|async)">
{{item.body}}
</div>
_
私の質問は、どのようにこれを行うことができますか、またはサービスではなくコンポーネントでsubscribeを呼び出すことを本当に推奨していますか?
複雑なコンポーネントロジックをサービスに委任するのは良い習慣です
FromAngular Style Guide
コンポーネントのロジックを、ビューに必要なロジックのみに制限します。他のすべてのロジックはサービスに委任する必要があります。再利用可能なロジックをサービスに移動し、コンポーネントをシンプルにし、意図した目的に焦点を合わせてください。
どうして?ロジックは、サービス内に配置され、関数を介して公開されると、複数のコンポーネントによって再利用される場合があります。
どうして?サービスのロジックは単体テストでより簡単に分離できますが、コンポーネントの呼び出しロジックは簡単にモックできます。
どうして?依存関係を削除し、コンポーネントから実装の詳細を隠します。
どうして?コンポーネントのスリム化、トリム、フォーカスの維持。
Componentでサブスクライブすると、単一のhttp
リクエストを複数のobservers
と共有できます。そうしないと、DRY Principle
P:S複数のhttp
に対する単一のobservers
要求を共有するには、次のようなものが必要です。 share演算子。
_import {Observable} from 'rxjs';
import {share} from 'rxjs/operators'
export class dataService {
public data$=Observable<Idata[]>
constructor(http:HttpClient)
{
this.data$=this.http.get<Idata[]>('https://jsonplaceholder.typicode.com/posts').pipe(share());
}
public getPosts():Observable<Idata[]>
{
return this.data$
}
}
_
この演算子は
publish
の特殊化であり、オブザーバーの数が0から1になったときにサブスクリプションを作成し、オブザーバーの数がゼロに戻るまでサブスクリプションを後続のすべてのオブザーバーと共有します。処分した。
すばらしいです! ObservableとAsyncを試すことができます! app.componentで
public posts: Observable<posts[]>
getPostsFromService() {
this.posts = this.myService.getPosts();
}
そして、htmlに次のように記述します。
*ngFor="let post of posts | async"
そしてサービス
return this._http.get<posts>('https://jsonplaceholder.typicode.com/posts', httpOptions)
それを試して、動作するかどうかを確認してください!それがお役に立てば幸いです!
サービスメソッドを使用する場合は、次のような監視可能な応答を返す必要があります。
public getPosts(): Observable<IPosts[]> {
const data = {
'$type' : 'ReadRequest',
'query' : 'getPosts',
'parameters' : {}
};
return this.http.post(null, data)
.map(res => (<any>res)._body === '' ? {} : res.json().result)
.catch(this.handleError);
}
private handleError(error: any): Promise<any> {
return Promise.reject(error.message || 'Server error: ' + error);
}
IPosts
には、応答に応じたインターフェイスが記述されています。
任意のコンポーネントでこれを使用できます:
public posts: IPosts[] = [];
this.servicePosts.getPosts().subscribe(data => {
this.posts = data; // Fill data from response to component variable this.post
}, error => {
console.log(error);
});