تایپاسکریپت - چگونه در انگولار به سرویس مشترک شویم
من ۳ شیء دارم: - کامپوننت اول - سرویس اتصال - کامپوننت دوم
زمانی که مؤلفه اول تا شده/گسترش مییابد، باید مؤلفه دوم را از طریق سرویس گسترش/جمع کند.
در سرویس من تابعی به نام toggle() دارم و باید فقط یک متغیر بولی isOpen را تغییر دهد. در کنار آن تابع دیگری به نام getIsOpen() دارم که نوع بازگشتی آن Observable است. کد به این شکل است:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { of } from 'rxjs/internal/observable/of';
@Injectable()
export class ConnectService {
public isOpen = false;
public toggle(): void {
this.isOpen = !this.isOpen;
console.log('Im inside toggle');
}
public getIsOpen(): Observable<boolean>{
console.log('Im inside getIsOpen');
return of(this.isOpen);
}
}
در مؤلفه دوم سعی میکنم مشترک شوم:
public ngOnInit(): void {
this.connectionService.getIsOpen().subscribe(x => this.isFirstComponentExpanded = x);
}
اما تنها تأثیر فقط پس از بارگذاری صفحه است، بعد از کلیک، مؤلفه دوم جمع یا باز نمیشود. چگونه میتوان به هر تغییر داخل سرویس گوش داد بدون استفاده از event emitter (من باید از هر نوع event emitter اجتناب کنم، فقط observables، subscribes و subjects).
پاسخ شماره ۱
of(this.isOpen) تنها یک بار مقدار را منتشر میکند. چیزی که شما نیاز دارید چیزی شبیه BehaviorSubject است، که همیشه آخرین مقدار خود را منتشر میکند.
@Injectable()
export class ConnectService {
public isOpen = new BehaviorSubject<boolean>(false);
public toggle(): void {
this.isOpen.next(!this.isOpen.value);
console.log('Im inside toggle');
}
}
و در کامپوننت خود میتوانید مستقیماً به موضوع خود مشترک شوید، نیازی به ایجاد یک Observable اضافی نیست:
public ngOnInit(): void {
this.connectionService.isOpen.subscribe(x => this.isFirstComponentExpanded = x);
}
پاسخ شماره ۲
isOpen یک boolean است. یک boolean فقط یک نوع اولیه است و هیچ قابلیت انتشار/اشتراک ندارد.
آنچه شما میخواهید یک Observable است که بتوانید واقعاً به آن مشترک شوید. در اینجا از یک BehaviorSubject استفاده خواهیم کرد، زیرا میتوانید یک مقدار اولیه به آن بدهید.
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/internal/Observable';
import { of } from 'rxjs/internal/observable/of';
@Injectable()
export class ConnectService {
public isOpen$ = new BehaviorSubject(false);
public toggle(): void {
this.isOpen$.next(!this.isOpen$.getValue());
console.log('Im inside toggle');
}
public getIsOpen(): Observable<boolean>{
console.log('Im inside getIsOpen');
return this.isOpen$;
}
}
سپس با استفاده از this.connectService.isOpen$.subscribe(isOpen => ...) به آن مشترک شوید.
