我有一个用户ID列表,对于列表中的每个用户,我想要检索额外的信息。 所以我想知道列表何时更改,以及每个用户的信息何时更改。 例如:
如果Anna的年龄发生变化,我希望能够更新列表,如果其他用户被添加到列表中,我也想跟踪它。
这就是我所做的:
private getUserData(userId:string):Observable<User>{...}
let userIds$:Observable<string[]> = getUserIds();
let users$ = userIds$.flatMap(x=>x) //get the string[]
.map(userId => this.getUserData(chatId)) //for each ID get the data
.mergeAll();
users$.subscribe(x =>{console.log(x)});
这种做了我想要的,但我的问题是每次更新列表(添加元素或删除)时,列表中的每个元素都会再次订阅更改。 因此,例如,如果我在列表中添加2个元素,然后更新Anna的年龄,我会收到Anna 3次的对象。
对于我所读过的内容,switchMap可能会修复它,但我已经尝试过使用它,而且我还没有能够使它工作。
由于
答案 0 :(得分:3)
欢迎使用Stack Overflow!
您需要的是发出一个值,该值是当前和上一个对象列表之间的差异。
使用lodash
difference
函数可以创建差异。
让我们假设数据结构如下:
[
{ name: 'Anna', age: 28 },
{ name: 'Peter', age: 23 },
{ name: 'Paul', age: 21 },
]
可以通过多种方式回答您的问题,但我提出的解决方案是:
BehaviorSubject
,它会在更改时发出整个数组,并Observable
发出差异。BehaviorSubject
我们有一个新数组。编辑:如果有人阅读此内容有创建完全反应式解决方案的雄心,请考虑使用
scan
运算符来包含 在一个流中具有完整功能的状态。 (剧透:你会重新发明redux什么不是坏事)。这里的例子是为了简单起见而写的。
我不会尝试模拟您的实施(您从服务器API获取数据),但我会给您一个可以从中获取灵感的模式。
const userList = {
current: [],
previous: [],
};
const userListChanged$ = new Rx.BehaviorSubject(userList.current);
const userListDifference$ = userListChanged$.map(current => {
return _.difference(current, userList.previous);
});
function currentToPrevious() {
userList.previous = [].concat(userList.current);
}
function addUser(name, age) {
currentToPrevious();
userList.current.push({name, age});
userListChanged$.next(userList.current);
}
function modifyUser(index, object) {
currentToPrevious();
userList.current[index] = Object.assign({}, userList.current[index], object);
userListChanged$.next(userList.current);
}
userListChanged$.subscribe(value => console.log('list', value));
userListDifference$.subscribe(value => console.log('diff', value));
addUser('Peter', 29);
addUser('Tom', 30);
addUser('Anna', 21);
modifyUser(2, { age: 20 });
userListDifference$
输出:
[{name:&#39; Peter&#39;,age:29}]
[{name:&#39; Tom&#39;,age:30}]
[{name:&#39; Anna&#39;,age:21}]
[{name:&#39; Anna&#39;,age:20}]
userListChanged$
输出:
[{name:&#39; Peter&#39;,age:29}]
[{name:&#39; Peter&#39;,年龄:29},{姓名:&#39; Tom&#39;,年龄:30}]
[{name:&#39; Peter&#39;,年龄:29},{姓名:&#39; Tom&#39;,年龄:30},{姓名:&#39; Anna&#39;,年龄:21}]
[{name:&#39; Peter&#39;,年龄:29},{姓名:&#39; Tom&#39;,年龄:30},{姓名:&#39; Anna&#39;,年龄:20}]