Angular 如何创建自定义 QueryParams 并将它们传递给 Router 的 NavigationExtras?

How to create custom QueryParams and pass them to Router's NavigationExtras in Angular?

我正在尝试在我的 Angular 应用程序中实施数据过滤。一般的想法是,用户从下拉字段中选择过滤器,然后单击一个按钮,将过滤器的键值对附加到路由。

我有 2 个用于过滤数据的下拉字段。

<!-- CHOOSE ENTITY TYPE DROPDOWN -->
<div class="row mt-3 text-center">
    <div class="col">
        <mat-form-field>
            <mat-label>Entity Type</mat-label>
            <mat-select
                [formControl]="filterEntityType"
                multiple
            >
                <mat-option
                    *ngFor="let option of entityTypes"
                    [value]="option"
                >
                    {{ option }}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </div>
</div>

<!-- CHOOSE PUBLISHER DROPDOWN -->
<div class="row text-center">
    <div class="col">
        <mat-form-field>
            <mat-label>Publisher</mat-label>
            <mat-select
                [formControl]="filterPublisher"
                multiple
            >
                <mat-option
                    *ngFor="let option of publishers"
                    [value]="option"
                >
                    {{ option }}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </div>
</div>                    

用户做出选择,可以是多个,然后单击 Apply 按钮。

<button
    type="button"
    class="btn btn-primary btn-lg m-1"
    (click)="applyFilters()"
>
    Apply
</button>

点击按钮后,执行以下方法

applyFilters() {
    let appliedFilters: Params = [];

    if (this.filterEntityType.value && this.filterEntityType.touched) {
        this.filterEntityType.value.forEach(element => {
            appliedFilters.push({ ["type"]: element });
        });
    }
    if (this.filterPublisher.value && this.filterPublisher.touched) {
        this.filterPublisher.value.forEach(element => {
            appliedFilters.push({ ["publisher"]: element });
        });
    }
    this.router.navigate(["/workspace"], {
        queryParams: appliedFilters,
        relativeTo: this.route
    });
}

如您所见,我正在尝试创建一个类型为 Params 的局部变量 appliedFilters,并根据所选过滤器将 key-value 对推送到其中。 之后,我只是将 appliedFilters 从路由器的 NavigationExtras 传递给 queryParams

组件的默认URL(未选择过滤器时)/sample/workspace。 选择过滤器后,我想要一个看起来像这样的 URL /sample/workspace?type=footype1&type=footype2&publisher=foopublisher.

type 重复,因为接受了多个过滤器选择。

Howerver,路由器似乎无法读取 key-value 对,而是显示 Object。因此,我最终得到以下 URL /sample/workspace?0=%5Bobject%20Object%5D&1=%5Bobject%20Object%5D&2=%5Bobject%20Object%5D.

当要传递同一个键的多个值时,将它们以逗号分隔。同时传递 JSON 对象而不是数组作为查询参数。

applyFilters() {
    let appliedFilters = {};

    if (this.filterEntityType.value && this.filterEntityType.touched) 
        appliedFilters["type"]  = this.filterEntityType.value.toString();

    if (this.filterPublisher.value && this.filterPublisher.touched) 
        appliedFilters["publisher"] = this.filterPublisher.value.toString();

    this.router.navigate(["/workspace"], {
        queryParams: appliedFilters,
        relativeTo: this.route
    });
}