Subject
Event တစ်ခု ဖြစ်ပေါ်လာတိုင်း တစ်ခုခုကို လုပ်စေချင်ရင် Observable မှာ Subject
ဆိုတာရှိပါတယ်။ EventEmitter
နဲ့အတူတူပါပဲ Subject
ကပိုကောင်းတဲ့နည်းလမ်းဖြစ်လို့ အစားထိုးသုံးသင့်ပါတယ်။
အရင်ဆုံး EventEmitter
နဲ့စမ်းကြပါမယ်။ UserService
ထဲမှာ အခုလိုရေးပါ။
activatedEmitter = new EventEmitter<boolean>();
UsersComponent
ထဲမှာ button တစ်ခုထည့်လိုက်ပါ။
HTML
<button class="btn btn-primary" (click)="activate()">Activate Me</button>TypeScript
activate() {
this.userService.activatedEmitter.emit(true);
}
AppComponent
ကနေ subscribe လုပ်ပြီး true
ဖြစ်မှ စာပြပေးအောင် ရေးလိုက်ပါ။
HTML
<h1 *ngIf="isActivated">Activated!</h1>TypeScript
isActivated = false;ngOnInit() {
this.userService.activatedEmitter.subscribe((didActivate) => {
this.isActivated = didActivate;
});
}
ဒါဆိုရင် button နှိပ်လိုက်တာနဲ့ AppComponent
ကသိပြီး စာတန်းပြပေးမှာ ဖြစ်ပါတယ်။
ဆက်လက်ပြီး EventEmitter
နေရာမှာ Subject
ဘယ်လိုပြောင်းသုံးမလဲ ကြည့်ရပါမယ်။
UserService
ထဲမှာအခုလိုပြင်ပါ။ EventEmitter
နေရာမှာ အစားထိုးလိုက်တာ ပါပဲ။
import { Subject } from 'rxjs';activatedEmitter = new Subject<boolean>();
UsersComponent
ထဲက emit
နေရာမှာ next
လိုပြောင်းပေးရပါမယ်။
this.userService.activatedEmitter.next(true);
ဒီလိုပြောင်းလိုက်ယုံနဲ့ နဂိုအတိုင်း ပြန်အလုပ်လုပ်သွားမှာ ဖြစ်ပါတယ်။ Subscribe လုပ်ပြီး အသုံးပြုပြီဆိုရင် memory leak မဖြစ်စေဖို့ ngOnDestroy
မှာ unsubscribe လုပ်ဖို့မမေ့ပါနဲ့။ AppComponent
မှာ အခုလို ထပ်ထည့်ပါ။
sub: Subscription = new Subscription();ngOnInit() {
this.sub = this.userService.activatedEmitter.subscribe(...);
}ngOnDestroy() {
this.sub.unsubscribe();
}
Subject
က Observable ဖြစ်လို့ Operators တွေနဲ့လည်း တွဲသုံးလို့ ရသွားမှာ ဖြစ်ပါတယ်။ တစ်ခုသတိထားရမှာက @Output
နဲ့သုံးတဲ့အခါ EvenEmitter
ကိုသာသုံးရမှာဖြစ်ပြီး Subject
ကို ပြောင်းသုံးလို့ မရပါ။
BehaviorSubject
Subject
နဲ့အတူတူပါပဲ။ ဒါပေမဲ့ BehaviorSubject
ရဲ့ထူးခြားချက်က subscribe မလုပ်ခင်ကပြောင်းလဲသွားခဲ့တဲ့ data ကိုရယူနိုင်ခြင်းပဲ ဖြစ်ပါတယ်။
ဆိုလိုတာက Subject
သည် emit လုပ်လိုက်တဲ့ data ကိုမသိမ်းထားပါ။ ဒါကြောင့် subscribe မလုပ်ခင်က emit လုပ်လိုက်တဲ့ data ကို subscribe လုပ်သူက လက်ခံရရှိလိုက်မှာ မဟုတ်ပါ။
ဥပမာစမ်းသပ်နိုင်ဖို့ AppComponent
မှာအခုလိုရေးပါ။
subject = new Subject<number>();
sub2: Subscription = new Subscription();testSubject() {
this.subject.next(1);
this.sub2 = this.subject.subscribe((num) => {
console.log('num is : ' + num);
});
this.subject.next(2);
}ngOnInit() {
this.testSubject();
}ngOnDestroy() {
this.sub2.unsubscribe();
}
console ကိုကြည့်လိုက်ရင် num is : 2 ပဲထွက်လာတာ တွေ့ရမှာပါ။
ဒီလိုဖြစ်ရတာက next(1)
ကိုလုပ်ချိန်မှာ Subject
ကို subscribe မလုပ်ရသေးတာကြောင့်ဖြစ်ပါတယ်။ next(2)
လုပ်ပြီးချိန်မှာတော့ subscribe လုပ်ပြီးပြီဖြစ်လို့ log ထွက်လာတာပဲဖြစ်ပါတယ်။
ဆက်လက်ပြီး BehaviorSubject
ကိုစမ်းသပ်ဖို့ AppComponent
မှာပဲဆက်ပြီး အောက်ပါ code တွေရေးပါ။
behaviorSubject = new BehaviorSubject<number>(0);
sub3: Subscription = new Subscription();testBehaviorSubject() {
this.behaviorSubject.next(1);
this.sub3 = this.behaviorSubject.subscribe((num) => {
console.log('[Behaviour] num is : ' + num);
});
this.behaviorSubject.next(2);
}ngOnInit() {
this.testBehaviorSubject();
}ngOnDestroy() {
this.sub3.unsubscribe();
}
BehaviorSubject
က initial variable တစ်ခု သတ်မှတ်ပေးဖို့ လိုတာကြောင့် 0
ထည့်ထားတာ တွေ့ရမှာပါ။ ရလဒ်ကတော့ အခုလို တွေ့ရမှာပါ။
1
ရော 2
ပါလက်ခံရရှိတာ တွေ့ရမှာ ဖြစ်ပါတယ်။ ဒါကြောင့် လက်ရှိ data ကိုလည်းလိုချင်တယ် နောက်ထပ် emit လုပ်မဲ့ data ကိုလည်းလိုချင်ရင် BehaviorSubject
ကိုသုံးပါ။ လက်ရှိ data ကိုမလိုချင်ပဲ နောက်ထပ် emit လုပ်မဲ့ data အသစ်ကိုပဲ လိုချင်ရင်တော့ Subject
ကို အသုံးပြုနိုင်ပါတယ်။
Prevent pushing data to Subjects
Subjects (Subject
and BehaviorSubject
) တွေက emit လုပ်နိုင်သလို subscribe လည်းလုပ်နိုင်ပါတယ်။ ကိုယ်ရေးထားတဲ့ Subjects ကို subscribe လုပ်ခွင့်ပဲပေးပြီး emit လုပ်ခွင့် မပေးချင်ရင် အခုလို ကာကွယ်ထားလို့ ရပါတယ်။
Subject
လေ့လာတုံးက ရေးသားခဲ့တာကိုပဲ ပြုပြင်ပြီး လေ့လာကြပါမယ်။ အရင်ဆုံး UserService
မှာအခုလိုပြင်ရေးပါ။
export class UserService {
private activatedEmitter = new Subject<boolean>();
activateObservable = this.activatedEmitter.asObservable(); doActivate() {
this.activatedEmitter.next(true);
}...
}
နဂိုရေးသားခဲ့တဲ့ Subject
ကို private လုပ်လိုက်ပါတယ်။ ဒါကြောင့် service ပြင်ပက access လုပ်လို့ရတော့မှာ မဟုတ်ပါ။ Subject
ကို asObservable()
သုံးပြီး Observable တစ်ခုအနေနဲ့ ပြောင်းယူလိုက်ပါတယ်။ ဒါကြောင့် ခေါ်သုံးမဲ့သူတွေဟာ activateObservable
ကိုပြောင်းခေါ်ပေးရမှာ ဖြစ်သလို subscribe
ပဲလုပ်လို့ရတော့မှာလည်း ဖြစ်ပါတယ်။ ဒါကြောင့် emit လုပ်ဖို့အတွက် service ထဲမှာပဲ method တစ်ခုနဲ့ရေးထားလိုက်တာ ဖြစ်ပါတယ်။
ဆက်လက်ပြီး UsersComponent
မှာအခုလို ပြင်ပေးပါ။
activate() {
this.userService.doActivate();
}
ပြီးရင်တော့ AppComponent
မှာ အောက်ပါအတိုင်း activatedObservable
ကို ပြောင်းခေါ်လိုက်ပါ။
ngOnInit() {
this.sub = this.userService.activateObservable.subscribe();
...
}
ရလဒ်ကတော့ အတူတူပဲဖြစ်ပေမဲ့ Subject
ကိုတိုက်ရိုက် access လုပ်တာ မဟုတ်တော့ပဲ Observable ကနေသာ access လုပ်ရတော့တာ ဖြစ်လို့ မှားယွင်းပြီး next()
ခေါ်မိမှာတွေကို ကာကွယ်ပြီးသား ဖြစ်သွားပါတယ်။
Of
Argument တွေကို observable sequence အဖြစ် ပြောင်းလဲပေးတာ ဖြစ်ပါတယ်။ AppComponent
မှာ အခုလို စမ်းနိုင်ပါတယ်။
ngOnInit() {
of('A', 'B', 'C', 'D').subscribe((data) => console.log(data));
of([1, 2, 3]).subscribe((data) => console.log(data));
}
ရလဒ်အနေနဲ့ အခုလို ထွက်လာမှာ ဖြစ်ပါတယ်။ argument တစ်ခုကို emit တစ်ခါလုပ်ပေးတာ တွေ့ရမှာပါ။
From
Observable မဟုတ်တာကို Observable အဖြစ် convert လုပ်ပေးပါတယ်။ Promise ကို Observable ပြောင်းရာမှာ အသုံးများပါတယ်။
ngOnInit() {
from([1, 2, 3]).subscribe((data) => console.log(data)); let asyncTask = new Promise((resolve, reject) => resolve('Hi'));
from(asyncTask).subscribe((data) => console.log(data));
}
ရလဒ်အနေနဲ့ အခုလို ထွက်လာမှာ ဖြစ်ပါတယ်။ Array ကိုထည့်ပေးလိုက်တဲ့အခါ of
နဲ့မတူတဲ့ ရလဒ်ကို ထုတ်ပေးတာ သတိပြုပေးပါ။
Previous: Operators
Next: Http Requests