अद्यतन: 9/24/16 कोणीय 2.0 स्थिर
यह प्रश्न अभी भी बहुत सारे ट्रैफ़िक प्राप्त करता है, इसलिए, मैं इसे अपडेट करना चाहता था। अल्फा, बीटा और 7 आरसी उम्मीदवारों से परिवर्तन की पागलपन के साथ, मैंने अपने एसओ जवाब अपडेट करना बंद कर दिया जब तक वे स्थिर नहीं हो गए।
इस का उपयोग कर के लिए एकदम सही मामला है विषयों और ReplaySubjects
मैं व्यक्तिगत रूप से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();
लेकिन यह बहुत कुछ है और इसका मतलब है कि आपको इसे करने के लिए एक फ़ंक्शन की आवश्यकता है। FlatMap दर्ज करें :
var myThing = http.get('path').flatMap(result1 =>
http.get('other/' + result1).flatMap(response2 =>
http.get('another/' + response2)));
स्वीट, var
एक अवलोकनीय है जो अंतिम http कॉल से डेटा प्राप्त करता है।
ठीक है, बहुत अच्छा है, लेकिन मुझे एक कोणीय 2 सेवा चाहिए!
तुम मुझे मिल गए:
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
कि आपके विभिन्न सेवा कार्यों पर अब जोर दिया जा सकता है।
यदि आप एक कॉल से सीधे एक अवलोकन योग्य लौटना चाहते थे, तो आप कुछ ऐसा कर सकते थे:
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
अपने दम पर धारा हूं अगर मुझे अन्य घटकों से इस तक पहुंचने की आवश्यकता होती है, लेकिन मैं दोनों तरीकों से काम कर सकता हूं ...
यहां एक प्लंकर है जो एक इवेंट एमिटर के साथ एक मूल सेवा दिखाता है: प्लंकर