【问题标题】:Collect / Concat objects emitted from switchMap into an array收集/连接从 switchMap 发出的对象到一个数组中
【发布时间】:2021-07-14 21:40:46
【问题描述】:

我正在尝试为链接对象动态构建一个数组。动态地,因为我需要读取 Ngrx Store 并获取参数。 就像在热图中一样

public linksObject = [
    {
        name: 'Consumption',
        link: ['../consumption'],
    },
    {
        name: 'Heatmap',
        link: ['../heatmap&res=foo'],
    }
 ];
 

我有一个构建单个对象的 switchMap,但我需要将它附加到 this.linkObjects

第二个 switchMap 正在获取一个角色数组,例如 ['admin', 'test', 'field_engineer'] 并在 getLinkObjects 内部构建对象:

{name: label, link:['..\ ...']}

pages 只是一个静态标签列表 ['consumption', 'heatmap']

    public getLinkObjects(roles: string[]): Observable<any> {
        return from(this.pages).pipe(
            switchMap(
                (page): Observable<ILinksObject> =>
                    from(roles).pipe(
                        map((role) => ({
                            name: page,
                            link: [`../${page}&role=${role}`],
                        })),
                    ),
            ),
        );
    }
this.fetchRoles()
    .pipe(
        switchMap((roles: IUserSite[]) => this.getCurrentRoles(roles)),
        switchMap((role: string[]) => this.getLinkObjects(role)),
        // concat the objects emitted by switchMap
    )
    .subscribe();

我尝试了以下 3 种方法,但没有奏效:

  • 在订阅中添加推送
  • 添加水龙头
this.fetchRoles()
    .pipe(
        switchMap((roles: IUserSite[]) => this.getCurrentRoles(roles)),
        switchMap((role: string[]) => this.getLinkObjects(role)),
        // concat the objects emitted by switchMap
    )
    .subscribe(this.linkObjects.push);
this.fetchRoles()
    .pipe(
        switchMap((roles: IUserSite[]) => this.getCurrentRoles(roles)),
        switchMap((role: string[]) => this.getLinkObjects(role)),
        tap((role) => this.linkObjects.push(role))
        // concat the objects emitted by switchMap
    )
    .subscribe();
        this.fetchRoles()
            .pipe(
                switchMap((roles: IUserSite[]) => this.getCurrentRoles(roles)),
                switchMap((role: string[]) => this.getLinkObjects(role)),
                tap(console.log), // this gets printed
                reduce((acc, role) => acc.concat(role), this.linksObject),
                tap(console.log), // this does not get printed
            )
            .subscribe(console.log);

我需要帮助指出正确的 rxjs 操作员的使用方向,并帮助排除这两种解决方案不起作用的原因。

【问题讨论】:

    标签: angular rxjs observable rxjs-pipeable-operators


    【解决方案1】:

    浏览这段代码:

    this.fetchRoles()
        .pipe(
            switchMap((roles: IUserSite[]) => this.getCurrentRoles(roles)),
            switchMap((role: string[]) => this.getLinkObjects(role)),
            tap((role) => this.linkObjects.push(role))
            // concat the objects emitted by switchMap
        )
        .subscribe();
    

    假设this.fetchRoles() 发出UserSites 的数组。

    第一个 switchMap 将取消任何现有请求并获取this.fetchRoles() 返回的数组中所有用户站点的当前角色。这似乎发出了单个字符串数组。 (我不清楚这些字符串包含什么以及它们与链接对象名称和链接的关系}

    第二个 switchMap 将取消任何现有请求并获取字符串数组的链接对象。这似乎返回了一个角色?

    第二个 switchMap 发出的role 的类型是什么? (如果您将鼠标悬停在 tap 运算符中的 (role) 上,您可以在 IDE 中轻松看到这一点。)

    你能确认这是预期的吗?如果这不是预期的,您是否可以修改您的问题以用文字指定每个操作员的预期输入和输出应该是什么?

    更新: 我强烈建议您输入您的“角色”:

    export interface Role {
       name: string,
       link: string[]
    }
    

    那么你的getLinkObjects就可以强类型化了:

    public getLinkObjects(roles: string[]): Observable<Role>
    

    这应该允许您的水龙头工作,因为它是正确类型的附加到数组:

    tap(role => this.linkObjects.push(role))
    

    【讨论】:

    • 感谢您查看此内容,我编辑了问题以回答您的问题。我的编辑澄清了吗?
    • tap方法中role的类型是什么?是any 类型吗?
    • 角色:ILinksObject;接口 ILinksObject { 名称:字符串;链接:字符串[]; }
    • 看来它们已经在任何地方都被强类型化了?您是否在某处看到错误?还是只是不将其附加到数组中?
    • 天啊!!你找对地方了!那个水龙头线有一个拼写错误,当我在那里添加类型时它起作用了!它的this.linksObject 不是this.linkObject
    猜你喜欢
    • 1970-01-01
    • 2022-12-15
    • 2021-12-07
    • 1970-01-01
    • 2013-04-25
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多