GÜNCELLEME: 9/24/16 Açısal 2.0 Kararlı
Bu soru hala çok fazla trafik alıyor, bu yüzden güncellemek istedim. Alfa, Beta ve 7 RC adaylarındaki değişikliklerin çılgınlığıyla, kararlı hale gelene kadar SO cevaplarımı güncellemeyi bıraktım.
Bu, Konular ve Yeniden Oynatma Konuları kullanmak için mükemmel bir durumdur.
Ben şahsen kullanım tercih ReplaySubject(1)
yeni aboneler bile geç eklediğinizde son saklanan değer iletilmesine izin veren gibidir:
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
Böylece, geç eklemem veya daha sonra yüklemem gerekse bile her zaman en son aramayı alabilir ve geri aramayı kaçırma konusunda endişelenmeyebilirim.
Bu, aynı akışı aşağı doğru itmek için kullanmanıza da olanak tanır:
project.next(5678);
//output
//Subscription Streaming: 5678
Peki ya aramayı yalnızca bir kez yapmanız gerektiğinden% 100 eminseniz? Konuları ve gözlemlenebilirleri açık bırakmak iyi değildir ama her zaman "Ya Olursa?"
AsyncSubject burada devreye girer.
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
Müthiş! Konuyu kapatmamıza rağmen yine de yüklediği son şeyle cevap verdi.
Başka bir şey de bu http çağrısına nasıl abone olduğumuz ve yanıtı nasıl ele aldığımızdır. Harita , yanıtı işlemek için harika.
public call = http.get(whatever).map(res => res.json())
Ama ya bu çağrıları iç içe geçirmemiz gerekirse? Evet, özel bir işlevi olan konuları kullanabilirsiniz:
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();
Ama bu çok fazla ve bunu yapmak için bir işleve ihtiyacınız olduğu anlamına geliyor. FlatMap'e girin :
var myThing = http.get('path').flatMap(result1 =>
http.get('other/' + result1).flatMap(response2 =>
http.get('another/' + response2)));
Tatlı, var
verileri son http çağrısından alan bir gözlemlenebilir.
Tamam bu harika ama bir angular2 hizmeti istiyorum!
Anladım:
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);
}
}
Gözlemcilerin ve gözlemlenebilirlerin büyük bir hayranıyım, bu yüzden bu güncellemenin yardımcı olacağını umuyorum!
Orijinal Cevap
Bunun kullanmanın kullanımı durum olduğunu düşünüyorum gözlemlenebilir Konu veya .Angular2
EventEmitter
Hizmetinizde EventEmitter
, üzerine değerler aktarmanıza izin veren bir yaratırsınız. In Alpha 45 Birlikte dönüştürmek zorunda toRx()
, ama bu kadar içinde ki kurtulmak için çalıştığını biliyor Alpha 46 basitçe dönmek mümkün olabilir EvenEmitter
.
class EventService {
_emitter: EventEmitter = new EventEmitter();
rxEmitter: any;
constructor() {
this.rxEmitter = this._emitter.toRx();
}
doSomething(data){
this.rxEmitter.next(data);
}
}
Bu şekilde, EventEmitter
farklı servis işlevlerinizin artık zorlayabileceği bir tek var.
Doğrudan bir görüşmeden gözlemlenebilir bir kişiye geri dönmek isterseniz, şöyle bir şey yapabilirsiniz:
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();
});
});
}
Bu, bunu bileşende yapmanıza izin verir:
peopleService.myHttpCall('path').subscribe(people => this.people = people);
Ve hizmetinizdeki aramanın sonuçlarıyla uğraşın.
EventEmitter
Diğer bileşenlerden ona erişmem gerektiğinde akışı kendi başına oluşturmayı seviyorum , ancak her iki yolun da çalıştığını görebiliyordum ...
İşte olay yayıcılı temel bir hizmeti gösteren bir planlayıcı : Plunkr