[解決済み] Angular 2 ServiceからObservableを作成し返す
質問
これはベストプラクティスというより、質問です。3人のプレイヤーがいます。
Component
, a
Service
と
Model
. は
Component
は
Service
を呼び出してデータベースからデータを取得しています。その
Service
が使われています。
this.people = http.get('api/people.json').map(res => res.json());
を返すように
Observable
.
は
Component
をサブスクライブすることができます。
Observable
:
peopleService.people
.subscribe(people => this.people = people);
}
しかし、私が本当に欲しいのは
Service
を返すことです。
Array of Model
のデータから作成されたオブジェクトを返します。
Service
がデータベースから取得したデータから作成されたオブジェクトです。私は、この
Component
はこの配列を subscribe メソッドで作成することもできますが、サービス側がそれを行って
Component
.
どのようにすれば
Service
は新しい
Observable
を作成し、その配列を含んで、それを返しますか?
どのように解決するのですか?
UPDATE: 9/24/16 Angular 2.0 Stable(安定版)。
この質問はまだ多くのトラフィックを得るので、私はそれを更新したいと思いました。Alpha、Beta、および7つのRC候補からの変更の狂気によって、私は、安定するまで私のSO回答を更新するのを止めました。
I
個人的に
を好んで使用します。
ReplaySubject(1)
を使うことを好みます。これは、新しい購読者の登録が遅れた場合でも、最後に保存された値を渡すことができるからです。
let project = new ReplaySubject(1);
//subscribe
project.subscribe(result => console.log('Subscription Streaming:', result));
http.get('path/to/whatever/projects/1234').subscribe(result => {
//push onto subject
project.next(result));
//add delayed subscription AFTER loaded
setTimeout(()=> project.subscribe(result => console.log('Delayed Stream:', result)), 3000);
});
//Output
//Subscription Streaming: 1234
//*After load and delay*
//Delayed Stream: 1234
そのため、遅れて添付したり、後でロードする必要がある場合でも、常に最新の呼び出しを取得でき、コールバックを見逃す心配がありません。
これはまた、プッシュダウンするために同じストリームを使用することができます。
project.next(5678);
//output
//Subscription Streaming: 5678
しかし、100%確実に、一度だけ呼び出す必要がある場合はどうでしょうか?オープンなサブジェクトやオブザーバブルを残しておくのは良くないですが、常に
そこで AsyncSubject の出番です。
let project = new AsyncSubject();
//subscribe
project.subscribe(result => console.log('Subscription Streaming:', result),
err => console.log(err),
() => console.log('Completed'));
http.get('path/to/whatever/projects/1234').subscribe(result => {
//push onto subject and complete
project.next(result));
project.complete();
//add a subscription even though completed
setTimeout(() => project.subscribe(project => console.log('Delayed Sub:', project)), 2000);
});
//Output
//Subscription Streaming: 1234
//Completed
//*After delay and completed*
//Delayed Sub: 1234
すごい! 件名を閉じたにもかかわらず、最後に読み込んだもので返信しています。
もうひとつは、httpコールをどのように購読し、レスポンスを処理したかです。 マップ はレスポンスを処理するのに適しています。
public call = http.get(whatever).map(res => res.json())
しかし、これらの呼び出しをネストする必要がある場合はどうでしょうか?そうです、特別な関数でサブジェクトを使用することができます。
getThing() {
resultSubject = new ReplaySubject(1);
http.get('path').subscribe(result1 => {
http.get('other/path/' + result1).get.subscribe(response2 => {
http.get('another/' + response2).subscribe(res3 => resultSubject.next(res3))
})
})
return resultSubject;
}
var myThing = getThing();
しかし、それはたくさんあり、それを行うための関数が必要であることを意味します。入る フラットマップ :
var myThing = http.get('path').flatMap(result1 =>
http.get('other/' + result1).flatMap(response2 =>
http.get('another/' + response2)));
甘い、その
var
は最終的な http 呼び出しからデータを取得する observable です。
OKそれは素晴らしいですが、私はangular2サービスが欲しいです!
私はあなたを得た。
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { ReplaySubject } from 'rxjs';
@Injectable()
export class ProjectService {
public activeProject:ReplaySubject<any> = new ReplaySubject(1);
constructor(private http: Http) {}
//load the project
public load(projectId) {
console.log('Loading Project:' + projectId, Date.now());
this.http.get('/projects/' + projectId).subscribe(res => this.activeProject.next(res));
return this.activeProject;
}
}
//component
@Component({
selector: 'nav',
template: `<div>{{project?.name}}<a (click)="load('1234')">Load 1234</a></div>`
})
export class navComponent implements OnInit {
public project:any;
constructor(private projectService:ProjectService) {}
ngOnInit() {
this.projectService.activeProject.subscribe(active => this.project = active);
}
public load(projectId:string) {
this.projectService.load(projectId);
}
}
私はオブザーバとオブザーバブルの大ファンなので、このアップデートがお役に立てれば幸いです。
オリジナルの回答
を使うユースケースだと思います。
観測可能なサブジェクト
で、あるいは
Angular2
は
EventEmitter
.
あなたのサービスでは
EventEmitter
を作成し、その上に値をプッシュできるようにします。で
アルファ45
で変換する必要があります。
toRx()
で変換する必要があるのですが、それをなくそうと動いていたのは知っていたので
α46
を単純に返すことができるかもしれません。
EvenEmitter
.
class EventService {
_emitter: EventEmitter = new EventEmitter();
rxEmitter: any;
constructor() {
this.rxEmitter = this._emitter.toRx();
}
doSomething(data){
this.rxEmitter.next(data);
}
}
この方法では、単一の
EventEmitter
にプッシュすることができます。
もし、呼び出しから直接observableを返したければ、次のようにすることができます。
myHttpCall(path) {
return Observable.create(observer => {
http.get(path).map(res => res.json()).subscribe((result) => {
//do something with result.
var newResultArray = mySpecialArrayFunction(result);
observer.next(newResultArray);
//call complete if you want to close this stream (like a promise)
observer.complete();
});
});
}
そうすると、コンポーネントの中でこんなことができるようになります。
peopleService.myHttpCall('path').subscribe(people => this.people = people);
そして、サービス内で呼び出しの結果をいじります。
を作るのが好きです。
EventEmitter
ストリームを単独で作成するのが好きなのですが、他のコンポーネントからアクセスする必要がある場合に備えて、両方の方法が機能しているのを確認できました...
イベントエミッターを持つ基本的なサービスを示すプランカーです。 プランカー
関連
-
[解決済み] Angular/RxJS `Subscription` からいつ退会すればいいのか?
-
[解決済み] Angularの@Directiveと@Componentの比較
-
[解決済み] Angular - すべてのリクエストにヘッダを設定する
-
[解決済み] ngIf」は「div」の既知のプロパティではないため、バインドできない [重複] 。
-
[解決済み] Angular HTTP GET with TypeScript エラー http.get(...).map is not a function in [null].
-
[解決済み】Angular 6でサービスを生成する際に、InjectableデコレータでprovidedInの目的は何ですか?
-
[解決済み] Angular 2のパッシブリンク - <a href="">相当
-
[解決済み] Angular2の変更検出:ネストされたオブジェクトに対してngOnChangesが発生しない
-
[解決済み] Angular 2の無効化されたコントロールがform.valueに含まれない
-
[解決済み] ファイル 'app/hero.ts' is not a module error in console, where to store interfaces files in directory structure with angular2?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] NGIf else "の使い方を教えてください。
-
[解決済み] Angular - すべてのリクエストにヘッダを設定する
-
[解決済み】Delegation: AngularのEventEmitterまたはObservable
-
[解決済み】プロパティ 'map' が 'Observable<Response>' 型に存在しない。
-
[解決済み] Angular CLI Error: serveコマンドはAngularプロジェクトで実行する必要がありますが、プロジェクト定義が見つかりませんでした。
-
[解決済み] テンプレート駆動型とリアクティブ型の実用的な違いとは?
-
[解決済み] Angularアプリケーションが本番モードと開発モードのどちらで動作しているかを確認する方法
-
[解決済み] viewchildを使用して複数のviewchildrenにアクセスする
-
[解決済み] Angularでhttpのような静的データからObservableを作成する方法は?
-
[解決済み] angular ngModuleのentryComponentsとは何ですか?