更新:2016年9月24日Angular 2.0安定
この質問はまだ多くのトラフィックを得るので、更新したかったのです。Alpha、Beta、および7つのRC候補からの変更の狂気のため、SOの回答の更新は、それらが安定するまで停止しました。
これは、SubjectおよびReplaySubjectを使用する場合に最適です。
私は個人的に使用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
驚くばかり!件名を閉じても、最後に読み込んだもので返信しました。
もう1つは、その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();
しかし、それはたくさんあり、それを行うには関数が必要であることを意味します。入力FlatMapを:
var myThing = http.get('path').flatMap(result1 =>
http.get('other/' + result1).flatMap(response2 =>
http.get('another/' + response2)));
これvar
は、最後のhttp呼び出しからデータを取得するオブザーバブルです。
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);
}
}
私はオブザーバーとオブザーバブルの大ファンなので、この更新が役立つことを願っています!
元の回答
これはObservable Subjectまたはで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
さまざまなサービス機能がプッシュできる単一のものがあります。
呼び出しからオブザーバブルを直接返したい場合は、次のようにします。
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
他のコンポーネントからストリームにアクセスする必要がある場合に備えて、自分でストリームを作成するのが好きですが、両方の方法が機能しているのを見ることができました...
以下は、イベントエミッターを使用した基本的なサービスを示すプランカーです。Plunkr