在 Angular 9 中筛选广播 属性
Filter a broadcasted property in Angular 9
我有一个调用数据库的dbService!
//数据库服务代码------------------------
private changedEvents = new BehaviorSubject<IEvent[]>(null);
broadCastEvents = this.changedEvents.asObservable();
getEvents() {
this.http.get<IEvent[]>(this.configUrl + 'Event/GetEvents').subscribe(
(data: IEvent[]) => {
this.changedEvents.next(data)
});
}
在我的 ngOnInit 组件中,我开始收听这个
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data;
})
// this.dbService.getEvents();
}
现在所有这一切都像一个魅力!但现在我只对 this.events.type == 2
的记录感兴趣
我试过如下标准过滤!
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => event.eventTypeRefId == 2);
})
// this.dbService.getEvents();
}
但它会导致以下错误!?任何想法如何以更好的方式做到这一点(有效:-))
core.js:6241 ERROR TypeError: Cannot read property 'filter' of null
at SafeSubscriber._next (start-training.component.ts:26)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
at SafeSubscriber.next (Subscriber.js:122)
at Subscriber._next (Subscriber.js:72)
at Subscriber.next (Subscriber.js:49)
at BehaviorSubject._subscribe (BehaviorSubject.js:14)
at BehaviorSubject._trySubscribe (Observable.js:42)
at BehaviorSubject._trySubscribe (Subject.js:81)
at BehaviorSubject.subscribe (Observable.js:28)
at Observable._subscribe (Observable.js:76)
ngOnInit(): void {
this.dbService.broadCastEvents.pipe(filter(event => event.eventTypeRefId == 2)).subscribe(data => {
this.events = data
})
// this.dbService.getEvents();
}
有多种方法。一种方法是像您一样使用数组 filter
。其他方法是使用 RxJS filter
管道,如 @enno.void 所示。但是,当通知为 null
时,这两种方法仍可能会引发错误。而且由于你的 BehaviorSubject
的默认值为空,所以很可能再次遇到错误。
它的一个解决方法是将 ReplaySubject
与缓冲区 1 一起使用。它与 BehaviorSubject
相似,因为它 holds/buffer 最后发出的值并在订阅后立即发出,除非不需要默认值。因此减少了对初始 null
值的需求。
尝试以下方法
private changedEvents = new ReplaySubject<IEvent[]>(1);
broadCastEvents = this.changedEvents.asObservable();
...
现在,如果您将 null
或 undefined
推送到 observable,错误可能仍然会发生。因此,在过滤条件中,您也可以检查值的真实性。
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => {
if (event) {
return event.eventTypeRefId == 2;
}
return false;
});
});
}
我有一个调用数据库的dbService!
//数据库服务代码------------------------
private changedEvents = new BehaviorSubject<IEvent[]>(null);
broadCastEvents = this.changedEvents.asObservable();
getEvents() {
this.http.get<IEvent[]>(this.configUrl + 'Event/GetEvents').subscribe(
(data: IEvent[]) => {
this.changedEvents.next(data)
});
}
在我的 ngOnInit 组件中,我开始收听这个
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data;
})
// this.dbService.getEvents();
}
现在所有这一切都像一个魅力!但现在我只对 this.events.type == 2
的记录感兴趣我试过如下标准过滤!
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => event.eventTypeRefId == 2);
})
// this.dbService.getEvents();
}
但它会导致以下错误!?任何想法如何以更好的方式做到这一点(有效:-))
core.js:6241 ERROR TypeError: Cannot read property 'filter' of null
at SafeSubscriber._next (start-training.component.ts:26)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
at SafeSubscriber.next (Subscriber.js:122)
at Subscriber._next (Subscriber.js:72)
at Subscriber.next (Subscriber.js:49)
at BehaviorSubject._subscribe (BehaviorSubject.js:14)
at BehaviorSubject._trySubscribe (Observable.js:42)
at BehaviorSubject._trySubscribe (Subject.js:81)
at BehaviorSubject.subscribe (Observable.js:28)
at Observable._subscribe (Observable.js:76)
ngOnInit(): void {
this.dbService.broadCastEvents.pipe(filter(event => event.eventTypeRefId == 2)).subscribe(data => {
this.events = data
})
// this.dbService.getEvents();
}
有多种方法。一种方法是像您一样使用数组 filter
。其他方法是使用 RxJS filter
管道,如 @enno.void 所示。但是,当通知为 null
时,这两种方法仍可能会引发错误。而且由于你的 BehaviorSubject
的默认值为空,所以很可能再次遇到错误。
它的一个解决方法是将 ReplaySubject
与缓冲区 1 一起使用。它与 BehaviorSubject
相似,因为它 holds/buffer 最后发出的值并在订阅后立即发出,除非不需要默认值。因此减少了对初始 null
值的需求。
尝试以下方法
private changedEvents = new ReplaySubject<IEvent[]>(1);
broadCastEvents = this.changedEvents.asObservable();
...
现在,如果您将 null
或 undefined
推送到 observable,错误可能仍然会发生。因此,在过滤条件中,您也可以检查值的真实性。
ngOnInit(): void {
this.dbService.broadCastEvents.subscribe(data => {
this.events = data.filter(event => {
if (event) {
return event.eventTypeRefId == 2;
}
return false;
});
});
}