【发布时间】:2019-06-26 07:16:45
【问题描述】:
我需要过滤一个递归对象数组。 每个对象代表一个 webapp 路由/url。这个url可以被限制为某个角色(permission=true|false),每个url都可以有子url...递归。
编辑: 复杂的部分是过滤需要一个异步函数调用(我的项目中有这个特定需求)。 这就是为什么我尝试用 RXJS 来做,但我可以用标准数组函数 + async/await 来做......
我也借此机会学习了更多 rxjs,这就是为什么我想要一个面向 rxjs 的答案(它处理异步,这是一个好方法吗?)。谢谢
拥有这个数组:
[
{
id: 'level 1.1',
permission: true,
children: [
{
id: 'level 2.1',
permission: false,
children: [
{id: 'level 3.1'}
]
},
{
id: 'level 2.2',
permission: true,
children: [
{id: 'level 3.2'}
]
}
]
},
{
id: 'level 1.2'
},
{
id: 'level 1.3',
permission: false
}
]
我需要过滤它以获得类似的输出(只保留没有权限或真实的条目:
[
{
id: 'level 1.1',
permission: true,
children: [
{
id: 'level 2.2',
permission: true,
children: [
{id: 'level 3.2'}
]
}
]
},
{
id: 'level 1.2'
}
]
我尝试的没有递归(注释代码),所以第一级过滤成功,但我不知道如何添加递归:
// simplified ASYNC filter function
promiseMe(x) {
return Promise.resolve().then(() => {
return x.permission === undefined || x.permission === true
});
}
// recursive function
const recursive = arr => {
return from(arr).pipe(
mergeMap(entry => from(this.promiseMe(entry)).pipe(
tap(y => console.log(y)),
filter(Boolean),
mapTo(entry),
tap(console.log),
mergeMap(item => {
// here I'm lost
// I need to affect the result of my async recursive function to item.children :
/*return recursive(item.children).pipe(
tap(res => {
console.log('RES', item, res)
item.children = res;
})
);*/
return of(item);
})
)),
toArray()
)
};
// main call
recursive(arr).subscribe(x => console.log('finally', x, JSON.stringify(x)))
这里是小提琴:https://stackblitz.com/edit/angular6-rxjs6-playground-idysbh?file=app/hello.component.ts
【问题讨论】:
-
嗨 Cétia,到目前为止,我仍然对您尝试实现的目标感到困惑。您能描述一下您的功能流程吗?听起来您有没有
permission字段的嵌套对象,并且您必须实现ajax 请求才能请求此标志,然后使用此新信息过滤您的原始列表。另一个问题:是否可以在执行任何流程之前将您的列表变平? -
你描述的没错。不可能展平,这是构建一个组=>子菜单
-
在我看来,rxjs 中的递归并不是那么自然。有一个名为
expand的运算符可用于满足您的需求。我前段时间写了一个类似问题的答案,看看:stackoverflow.com/questions/53129852/… -
也是不可能的,但我强烈建议您避免多次请求授权。对我来说,您应该解析您的对象并搜索每个必须检查的项目,然后执行单个请求,再次解析您的对象并设置授权标志。
标签: angular asynchronous filter rxjs