我想在启动时加载所有项目而不显示任何消息,但是在加载后一次。我想捕获订阅者中的任何新行并将其显示给桌面通知。
问题是,我不确定如何检查是否已加载所有先前的项目,以及该行是新项目还是来自先前现有项目。
this.items = this.af.database.list('notifications/'+this.uid+'/');
this.items.subscribe(list => {
list.forEach(row => {
// doing something here...
});
// once all the rows are finished loading, then any new row, show desktop notification message
});
答案 0 :(得分:0)
我有最少代码的用户 lodash 。
// this varible holds the initial loaded keys
let loadedKeys = [];
this.items = this.af.database.list('notifications/'+this.uid+'/');
this.items.subscribe((list)=>{
// we skip it while initial load
if(!_.isEmpty(loadedKeys)){
// different is the new keys
let newKeys = _.difference(_.map(list, "$key"), loadedKeys);
if(!_.isEmpty(newKeys)){
// ... notification code here
}
}
loadedKeys = _.map(list, "$key");
});
答案 1 :(得分:0)
您正在寻找的行为是RxJS
中的default Subject方法。
点击this reactiveX url,按照Publish Subject
的大理石图表(Subject
中的RxJS
的等价物)。
所以你有两个简单的选择:
1)手动索引要显示的女性行like @bash replied
2)创建一个Rx.Subject()
并仅为其分配最新的行。然后,您在应用工作流程中订阅此主题。
方法2的优点是当出现新的.subscribe
时,它不会检索以前的数据。
修改:我写了this codepen作为实施自定义RxJS Subject
的指南。希望它有所帮助。
答案 2 :(得分:0)
假设您的行具有与上一行匹配的独特内容,则可以执行以下操作:
// A Row item has a unique identifier id
interface Row {
id: number;
}
this.rows: Row[];
this.items$ = this.af.database.list(`notifications/${this.uid}/`).pipe(
tap(list => {
// if rows is not array, first time...
if(!Array.isArray(this.rows)) {
// first time nothing to do
return;
}
// returns true if some item from list is not found in this.rows
const foundNewRow = list.some(item => {
return ! this.rows.find(row => row.id === item.id);
});
if (foundNewRow) {
// call method to show desktop message here
}
}
);
我使用了管道和水龙头算子(您必须导入)。如果您订阅this.items $,tap运算符将完成工作:
this.items$.subscribe((items => this.rows = items));
如果您不想在正常订阅时设置this.rows
,那么也可以在点击操作符中进行设置。但这将假定您仅将其用于检查现有项目与新项目之间的差异。