我可以为多个事件使用单个 BehaviorSubject 吗?
Can I use a single BehaviorSubject for multiple events?
在 Angular 8
中,我使用以下方法在添加新记录后刷新 Details
页面:
EventProxyService
export class EventProxyService {
private eventTracker = new BehaviorSubject<any>(undefined);
/* Allows subscription to the behavior subject as an observable */
getEvent(): BehaviorSubject<any> {
return this.eventTracker;
}
/* Allows updating the current value of the behavior subject */
setEvent(param: any): void {
this.eventTracker.next(param);
}
}
创建组件:
export class CreateComponent implements OnInit {
constructor(private eventProxyService: EventProxyService) { }
triggerAnEvent(param: any): void {
this.eventProxyService.setEvent(param);
}
}
详细组件:
export class DetailsComponent implements OnInit {
subscription;
constructor(private eventProxyService: EventProxyService) { }
ngOnInit() {
this.subscription = this.eventProxyService.getEvent().subscribe((param: any) => {
this.theTargetMethod(param);
);
}
theTargetMethod(param) {
this.record = param; //update record via new one passed from service
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
该方法按预期工作,但有时会出现类似的事件,例如需要刷新Details
页面的更新。所以,我想知道我是否应该为每个不同的事件创建一个新的 BehaviorSubject
对象 (eventTracker
)、getEvent
和 setEvent
方法,例如Update
事件?据我所知,可以使用单个 BehaviorSubject
,但是如果两个不同的事件向订阅者传递不一致的数据可能会出现问题。什么是正确的方法?
最简单的方法是创建一个类型 CustomEvent
(不会将其命名为 Event
,因为该类型已被使用)。您可以给它一个字段 eventType
或使用从 CustomEvent
扩展的 类 来区分使用哪种事件。
1。 eventType
字段
events.ts
export interface CustomEvent{
eventType: 'Update' | 'OtherEvent';
data: any; // Type unsafe, maybe narrow it down
}
EventProxy
export class EventProxyService {
private eventTracker = new BehaviorSubject<CustomEvent>(undefined);
getEvent(): BehaviorSubject<CustomEvent> { return this.eventTracker; }
setEvent(param: CustomEvent): void { this.eventTracker.next(param); }
}
add/get 事件
// Services omitted, too long
// add new event
this.eventProxyService.setEvent({
eventType: 'Update',
data: {/* Your data here */}
});
// listen to events
this.subscription = this.eventProxyService.getEvent()
// .filter(param => param.evenType === 'Update') // if you want only specific events
.subscribe((param: CustomEvent) => {
if (param.eventType === 'Update') {
this.theTargetMethod(param);
} else if (param.eventType === 'OtherEvent') {
// do something else
}
);
2。事件类
events.ts
export class CustomEvent {}
export class UpdateEvent extends CustomEvent {
constructor(
public newData: Data // Use a specific type and as many fields as you need
) {}
}
export class OtherEvent extends CustomEvent {
constructor(
public otherData: OtherData// Use a specific type and as many fields as you need
) {}
}
EventProxy
export class EventProxyService {
private eventTracker = new BehaviorSubject<CustomEvent>(undefined);
getEvent(): BehaviorSubject<CustomEvent> { return this.eventTracker; }
setEvent(param: CustomEvent): void { this.eventTracker.next(param); }
}
add/get 事件
// Services omitted, too long
// add new event
this.eventProxyService.setEvent(new UpdateEvent({
/* Your data here */
}));
// listen to events
this.subscription = this.eventProxyService.getEvent()
// .filter(param => param instanceof UpdateEvent) // if you want only specific events
.subscribe((param: CustomEvent) => {
if (param instanceof UpdateEvent) {
this.theTargetMethod(param);
} else if (param instanceof OtherEvent) {
// do something else
}
);
3。多个主题
EventProxy
export type EventType: 'update' | 'other';
export class EventProxyService {
// Use BehaviourSubject<SPECIFIC_TYPE> if possible
private updateEventTracker = new BehaviorSubject<any>(undefined);
private otherEventTracker = new BehaviorSubject<any>(undefined);
setEvent(type: EventType, param: any): void {
this.getEventTrackerForType(type).next(param);
}
getEvent(type?: EventType): BehaviorSubject<any> {
return this.getEventTrackerForType(type);
}
private getEventTrackerForType(type?:EventType): BehaviorSubject<any> {
switch(type) {
case 'update': return this.updateEventTracker;
case 'other': return this.otherEventTracker;
// if no type specified, return ALL events as one Observable (bonus)
default: return merge(
this.updateEventTracker,
this.otherEventTracker
)
}
}
// alternatively, create setEvent/getEvent methods for each subject specifically (setUpdateEvent/getUpdateEvent/...)
}
在 Angular 8
中,我使用以下方法在添加新记录后刷新 Details
页面:
EventProxyService
export class EventProxyService {
private eventTracker = new BehaviorSubject<any>(undefined);
/* Allows subscription to the behavior subject as an observable */
getEvent(): BehaviorSubject<any> {
return this.eventTracker;
}
/* Allows updating the current value of the behavior subject */
setEvent(param: any): void {
this.eventTracker.next(param);
}
}
创建组件:
export class CreateComponent implements OnInit {
constructor(private eventProxyService: EventProxyService) { }
triggerAnEvent(param: any): void {
this.eventProxyService.setEvent(param);
}
}
详细组件:
export class DetailsComponent implements OnInit {
subscription;
constructor(private eventProxyService: EventProxyService) { }
ngOnInit() {
this.subscription = this.eventProxyService.getEvent().subscribe((param: any) => {
this.theTargetMethod(param);
);
}
theTargetMethod(param) {
this.record = param; //update record via new one passed from service
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
该方法按预期工作,但有时会出现类似的事件,例如需要刷新Details
页面的更新。所以,我想知道我是否应该为每个不同的事件创建一个新的 BehaviorSubject
对象 (eventTracker
)、getEvent
和 setEvent
方法,例如Update
事件?据我所知,可以使用单个 BehaviorSubject
,但是如果两个不同的事件向订阅者传递不一致的数据可能会出现问题。什么是正确的方法?
最简单的方法是创建一个类型 CustomEvent
(不会将其命名为 Event
,因为该类型已被使用)。您可以给它一个字段 eventType
或使用从 CustomEvent
扩展的 类 来区分使用哪种事件。
1。 eventType
字段
events.ts
export interface CustomEvent{
eventType: 'Update' | 'OtherEvent';
data: any; // Type unsafe, maybe narrow it down
}
EventProxy
export class EventProxyService {
private eventTracker = new BehaviorSubject<CustomEvent>(undefined);
getEvent(): BehaviorSubject<CustomEvent> { return this.eventTracker; }
setEvent(param: CustomEvent): void { this.eventTracker.next(param); }
}
add/get 事件
// Services omitted, too long
// add new event
this.eventProxyService.setEvent({
eventType: 'Update',
data: {/* Your data here */}
});
// listen to events
this.subscription = this.eventProxyService.getEvent()
// .filter(param => param.evenType === 'Update') // if you want only specific events
.subscribe((param: CustomEvent) => {
if (param.eventType === 'Update') {
this.theTargetMethod(param);
} else if (param.eventType === 'OtherEvent') {
// do something else
}
);
2。事件类
events.ts
export class CustomEvent {}
export class UpdateEvent extends CustomEvent {
constructor(
public newData: Data // Use a specific type and as many fields as you need
) {}
}
export class OtherEvent extends CustomEvent {
constructor(
public otherData: OtherData// Use a specific type and as many fields as you need
) {}
}
EventProxy
export class EventProxyService {
private eventTracker = new BehaviorSubject<CustomEvent>(undefined);
getEvent(): BehaviorSubject<CustomEvent> { return this.eventTracker; }
setEvent(param: CustomEvent): void { this.eventTracker.next(param); }
}
add/get 事件
// Services omitted, too long
// add new event
this.eventProxyService.setEvent(new UpdateEvent({
/* Your data here */
}));
// listen to events
this.subscription = this.eventProxyService.getEvent()
// .filter(param => param instanceof UpdateEvent) // if you want only specific events
.subscribe((param: CustomEvent) => {
if (param instanceof UpdateEvent) {
this.theTargetMethod(param);
} else if (param instanceof OtherEvent) {
// do something else
}
);
3。多个主题
EventProxy
export type EventType: 'update' | 'other';
export class EventProxyService {
// Use BehaviourSubject<SPECIFIC_TYPE> if possible
private updateEventTracker = new BehaviorSubject<any>(undefined);
private otherEventTracker = new BehaviorSubject<any>(undefined);
setEvent(type: EventType, param: any): void {
this.getEventTrackerForType(type).next(param);
}
getEvent(type?: EventType): BehaviorSubject<any> {
return this.getEventTrackerForType(type);
}
private getEventTrackerForType(type?:EventType): BehaviorSubject<any> {
switch(type) {
case 'update': return this.updateEventTracker;
case 'other': return this.otherEventTracker;
// if no type specified, return ALL events as one Observable (bonus)
default: return merge(
this.updateEventTracker,
this.otherEventTracker
)
}
}
// alternatively, create setEvent/getEvent methods for each subject specifically (setUpdateEvent/getUpdateEvent/...)
}