typescript - سرویس Angular Observable دفعات دوم مشترک شدن کامپوننتها را فعال نمیکند
من در تلاش هستم که کامپوننت را به Subject سرویس مشترک کنم تا مطمئن شوم که اشتراک کامپوننت روی انتشار سرویس اجرا میشود.
مشکل این است که سابسکریپشن تنها دفعه اول فعال میشود و بعد از آن سابسکریپشن فعال نمیشود و همچنین observable دفعه دوم که سابسکریپشن متصل میشود، 0 را برمیگرداند.
کد زیر است:
export class StoreService {
private storesList : Subject<Array<KeyValue<string>>> = null;
constructor(private http: Http, private _uService: UserService) {
this.storesList = new Subject<Array<KeyValue<string>>>();
}
loadStores(): void{
this.getAllStores().subscribe(m=>{
debugger;
this.storesList.next(m);
});
}
storeListEvent(): Observable<Array<KeyValue<string>>>{
return this.storesList.asObservable();
}
}
در حالی که مؤلفه هست.
export class HeaderNavComponent implements OnInit, AfterViewInit,OnDestroy {
private storeUpdateSubscription = null;
constructor(private _userService: UserService, private cdRef: ChangeDetectorRef, private _storeService: StoreService, private router: Router, private location: Location) {
this.storeUpdateSubscription = this._storeService.storeListEvent().subscribe(stores => {
debugger;
this.appStore = stores;
this.verifySuperAdmin();
});
}
هدف این است که هر بار در کامپوننت به آن اشتراک فوق توجه شود
هنگامی که سرویس فروشگاه - loadStores فراخوانی میشود
پاسخ شماره ۱
شما در حال استفاده از یک الگوی ضد هستید: هرگز در همان سرویس به تماس سرویس اشتراک ندهید. شما باید تماس را بازگردانید و کامپوننت باید به این Observable اشتراک کند.
به هر حال، از آنجایی که storeList یک موضوع است، میتوانید انجام آن را ساده کنید:
this.getAllStores().subscribe(this.storesList);
زیرا یک موضوع نیز ناظر است
پاسخ شماره ۲
کد شما کامل نیست (به عنوان مثال، هیچ تابعی با نام getAllStores() یا storeListEvent() وجود ندارد، مشخص نیست که userService چه کاری انجام میدهد) بنابراین آنچه من قصد دارم بگویم ممکن است در مورد شما درست نباشد.
به هر حال، چیزی که به شما توصیه میکنم این است که منطق خود را در این مسیر ساده کنید
- موضوع را از StoreService حذف کنید
- متد
loadStores()را طوری بسازید که یک Observable برگرداند - در
HeaderNavComponentبه Observable بازگردانده شده توسطloadStores()مشترک شوید - منطق اشتراک را در متد
ngOnInit()قرار دهید نه در سازنده
اینگونه کد میتواند به نظر برسد
export class StoreService {
constructor(private http: Http, private _uService: UserService) {
}
loadStores(): Observable<Array<KeyValue<string>>> {
return this.getAllStores();
}
}
export class HeaderNavComponent implements OnInit, AfterViewInit,OnDestroy {
private storeUpdateSubscription = null;
constructor(private _userService: UserService, private cdRef: ChangeDetectorRef, private _storeService: StoreService, private router: Router, private location: Location) {}
ngOnInit() {
this.storeUpdateSubscription = this._storeService.subscribe(stores => {
debugger;
this.appStore = stores;
this.verifySuperAdmin();
});
}
}
نظرات اضافی
من فرض میکنم که متد getAllStores() از StoreService یک فراخوانی http را از طریق سرویس Http که در سازنده تعریف کردهاید، انجام میدهد
با نگاه کردن به کد شما getAllStores() یک Observable برمیگرداند، در غیر این صورت نمیتوانستید subscribe کنید
اگر این درست باشد، به جای اینکه به Observable بازگشتی از getAllStores() مشترک شوید تنها برای انتشار یک مقدار جدید با یک Observable دیگر (storesList) که HeaderNavComponent به آن مشترک میشود، میتوانید به سادگی HeaderNavComponent را به Observable بازگشتی از متد getAllStores() مشترک کنید
امیدوارم حالا این واضحتر باشد
