अद्यतन 2016-06-27: वेधशालाओं का उपयोग करने के बजाय, या तो उपयोग करें
- जैसा कि एक टिप्पणी में @Abdulrahman द्वारा अनुशंसित व्यवहार व्यवहार, या
- ReplaySubject, जैसा कि @Jason Goemaat ने एक टिप्पणी में सुझाया है
एक सब्जेक्ट एक ऑब्जर्वेबल (इसलिए हम subscribe()
इसे कर सकते हैं) और एक ऑब्जर्वर दोनों हैं (इसलिए हम next()
इसे नए मूल्य का अनुकरण करने के लिए कह सकते हैं )। हम इस सुविधा का फायदा उठाते हैं। एक विषय कई पर्यवेक्षकों के लिए मूल्यों को बहुस्त्र्पीय होने की अनुमति देता है। हम इस सुविधा का उपयोग नहीं करते हैं (हमारे पास केवल एक पर्यवेक्षक है)।
व्यवहार विषय विषय का एक प्रकार है। इसमें "वर्तमान मूल्य" की धारणा है। हम इसका फायदा उठाते हैं: जब भी हम एक ऑब्जर्विंगकंपोनेंट बनाते हैं, तो यह स्वचालित रूप से व्यवहार सर्वर से वर्तमान नेविगेशन आइटम मूल्य प्राप्त करता है।
नीचे दिए गए कोड और प्लंकर BehaviorSubject का उपयोग करते हैं।
ReplaySubject Subject का एक और संस्करण है। यदि आप वास्तव में उत्पादन होने तक इंतजार करना चाहते हैं, तो उपयोग करें ReplaySubject(1)
। जबकि BehaviorSubject को एक प्रारंभिक मूल्य (जो तुरंत प्रदान किया जाएगा) की आवश्यकता होती है, ReplaySubject नहीं करता है। ReplaySubject हमेशा सबसे हाल का मूल्य प्रदान करेगा, लेकिन चूंकि इसमें एक आवश्यक प्रारंभिक मूल्य नहीं है, इसलिए सेवा पहले मूल्य को वापस करने से पहले कुछ async ऑपरेशन कर सकती है। यह अभी भी सबसे हाल के मूल्य के साथ बाद में कॉल पर तुरंत आग लगा देगा। यदि आप केवल एक मूल्य चाहते हैं, first()
तो सदस्यता पर उपयोग करें । यदि आप उपयोग करते हैं तो आपको सदस्यता समाप्त करने की आवश्यकता नहीं है first()
।
import {Injectable} from '@angular/core'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
@Injectable()
export class NavService {
// Observable navItem source
private _navItemSource = new BehaviorSubject<number>(0);
// Observable navItem stream
navItem$ = this._navItemSource.asObservable();
// service command
changeNav(number) {
this._navItemSource.next(number);
}
}
import {Component} from '@angular/core';
import {NavService} from './nav.service';
import {Subscription} from 'rxjs/Subscription';
@Component({
selector: 'obs-comp',
template: `obs component, item: {{item}}`
})
export class ObservingComponent {
item: number;
subscription:Subscription;
constructor(private _navService:NavService) {}
ngOnInit() {
this.subscription = this._navService.navItem$
.subscribe(item => this.item = item)
}
ngOnDestroy() {
// prevent memory leak when component is destroyed
this.subscription.unsubscribe();
}
}
@Component({
selector: 'my-nav',
template:`
<div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div>
<div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>`
})
export class Navigation {
item = 1;
constructor(private _navService:NavService) {}
selectedNavItem(item: number) {
console.log('selected nav item ' + item);
this._navService.changeNav(item);
}
}
Plunker
मूल उत्तर जो एक ऑब्जर्वेबल का उपयोग करता है: (इसमें एक व्यवहार कोड का उपयोग करने की तुलना में अधिक कोड और तर्क की आवश्यकता होती है, इसलिए मैं इसकी अनुशंसा नहीं करता, लेकिन यह शिक्षाप्रद हो सकता है)
इसलिए, यहां एक कार्यान्वयन है जो एक EventEmitter के बजाय एक ऑब्जर्वेबल का उपयोग करता है । मेरे EventEmitter कार्यान्वयन के विपरीत, यह कार्यान्वयन वर्तमान navItem
में सेवा में चयनित स्टोर को भी संग्रहीत करता है , ताकि जब एक अवलोकन घटक बनाया जाता है, तो यह API कॉल के माध्यम से वर्तमान मूल्य को पुनः प्राप्त कर सकता है navItem()
, और फिर navChange$
वेधशाला के माध्यम से परिवर्तनों के बारे में सूचित किया जा सकता है ।
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/share';
import {Observer} from 'rxjs/Observer';
export class NavService {
private _navItem = 0;
navChange$: Observable<number>;
private _observer: Observer;
constructor() {
this.navChange$ = new Observable(observer =>
this._observer = observer).share();
// share() allows multiple subscribers
}
changeNav(number) {
this._navItem = number;
this._observer.next(number);
}
navItem() {
return this._navItem;
}
}
@Component({
selector: 'obs-comp',
template: `obs component, item: {{item}}`
})
export class ObservingComponent {
item: number;
subscription: any;
constructor(private _navService:NavService) {}
ngOnInit() {
this.item = this._navService.navItem();
this.subscription = this._navService.navChange$.subscribe(
item => this.selectedNavItem(item));
}
selectedNavItem(item: number) {
this.item = item;
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
@Component({
selector: 'my-nav',
template:`
<div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div>
<div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>
`,
})
export class Navigation {
item:number;
constructor(private _navService:NavService) {}
selectedNavItem(item: number) {
console.log('selected nav item ' + item);
this._navService.changeNav(item);
}
}
Plunker
घटक इंटरएक्शन कुकबुक उदाहरण भी देखें , जो Subject
वेधशालाओं के अतिरिक्त उपयोग करता है । हालांकि उदाहरण "माता-पिता और बच्चों के संचार," एक ही तकनीक असंबंधित घटकों के लिए लागू है।