基于数组 Angular 2 中 id 数量的动态 URL 参数

Posted

技术标签:

【中文标题】基于数组 Angular 2 中 id 数量的动态 URL 参数【英文标题】:Dynamic URL parameters based on number of id's in array Angular 2 【发布时间】:2017-12-30 14:12:07 【问题描述】:

我有一个名为 selectedItems 的数组,它是从多选下拉按钮填充的。如果选择了所有选项,SelectedItems 可能如下所示:

this.selectedItems: SearchItem[]= [
  "id":"abee232","itemName":"Attractions",
  "id":"b6b1a23","itemName":"Artists",
  "id":"08a58c8","itemName":"Performing Arts",
  "id":"444d047","itemName":"Sports"
];

我需要添加 id 值,但是已经选择了许多值,作为 http GET 请求中的参数。现在我的逻辑是这样的。

  private addRequestOptions(params: SearchItem[]): RequestOptions 
    let options: RequestOptions = new RequestOptions();
      options.params = new URLSearchParams();
    if (params != null) params.forEach((p: SearchItem) => 
      options.params.append("&collectionId", p.id);
    )
    console.log(options)
    return options;
  

  sortResults()
        let options: RequestOptions = this.addRequestOptions(this.selectedItems);
        this.pendingCardsService.collectionUuidUrl = 'http://address/cards/topbrands?perPage=25', options;
        this.pendingCardsBrandCollection();
  

我的 SearchItem 界面如下所示:

export interface SearchItem 
  id?: string;
  itemName?: string;

现在这会创建一个 requestOptions 对象,其中包含作为数组的值,但我的 http 请求未在网络选项卡的查询字符串参数字段中显示此内容。似乎 addRequestOptions() 工作正常,但未正确应用于获取请求。目标是最终得到一个类似这样的 URL:

'http://address/cards/topbrand?perpage=25&collectionId=idValue&collectionId=idValue&collectionId=idValue'

我被困住了如何做到这一点。任何帮助/提示/建议将不胜感激。

使用最终代码更新 我的问题是我在'http://address/cards/topbrands?perPage=25' ?perPage=25 中进行了硬编码,被读取为参数(这是正确的),因此由于参数已经存在,因此没有附加 id。我的最终代码最终看起来像这样让它正常工作:

  fetchPendingCardsBrandCollection(ids: SearchItem[], pageSize = '25'):Observable<Card[]> 
    const params = new URLSearchParams();
    params.set('perPage', pageSize);
    ids.forEach(id => params.append('collectionId', id.id));
    return this.http.get(this.collectionUuidUrl, params: params)
      .map(this.extractData)
  

使用我的函数调用此 http 请求函数,并将 SearchItems 作为参数传递。非常感谢@Praveen M 的帮助和@Jota.Toledo 的解决方案!

【问题讨论】:

【参考方案1】:

通过给它一个类型来更新现有的数据数组,这样在处理数组时出错的余地就会更小。

// Add the class to a ts file
export class Args 
 id: string;
 itemName: strngs;


dropdownList: Args[] = [];

// Declare the selectedItems is a type of Args class
selectedItems: Args[] = [];


this.dropdownList = [
  id:"abee232b6f3b06c3da1955fb270ced28", itemName:"Attractions",
  id:"b6b1a23b6a0ad3ab467284ca92bc7d59", itemName:"Artists",
  id:"08a58c804fa4eb462ad4e690a51864f6", itemName:"Performing Arts",
  id:"444d0472d7d94f569da6fd7a5608faba", itemName:"Sports"
];

// Now they are actual key value pair
this.selectedItems = [
  id:"abee232",itemName:"Attractions",
  id:"b6b1a23",itemName:"Artists",
  id:"08a58c8",itemName:"Performing Arts",
  id:"444d047",itemName:"Sports"
];

//CSV Format

private addRequestOptions(params: Args[]): RequestOptions 
  let options: RequestOptions = new RequestOptions();
  let list: string = "";
  options.params = new URLSearchParams();
  if (params != null) params.forEach((p: Args) => 
    list + p.id + ",";
  );
  options.params.set("collectionId", list);
  console.log(options);
  return options;


// Array of parameters format

private addRequestOptions(params: Args[]): RequestOptions 
  let options: RequestOptions = new RequestOptions();
  let list: string = "";
  options.params = new URLSearchParams();
  if (params != null) params.forEach((p: Args) => 
    options.params.append("collectionId", p.id);
  );
  console.log(options);
  return options;

这将为您作为agrs 传递给它的参数创建一个RequestOptions,您可以将其直接插入Get 方法中。

this.http.get(url, this.addRequestOptions(this.selectedItems))
  .map((res: any) => res.json() as any)
  .catch((err: Response) Observable.throw(console.log(err)));

import Http, RequestOptions, URLSearchParams from "@angular/http";
import "rxjs";
import Observable from "rxjs/Observable";

更新 现在您应该能够将selectedItems 变量作为addRequestOptions 参数传入,它将为所有ids 生成url 参数。

这篇文章展示了几种可以将值传递为Array of parameters的方法

【讨论】:

这应该产生类似http://address/cards/topbrand?perpage=25collectionId=id1,id2,id2,id4..... 很多后端框架都内置了将 key=value1&key=value2 解析为数组的支持,无需额外代码。通过使用 coma 方法,您需要创建一个解析器方法。 @Jota.Toledo 感谢您指出这一点,我不确定是否应该使用该方法。我现在已经用这两个选项更新了代码 您的答案中仍然有“至少它不是最佳实践”。你从哪里得到的?顺便说一句,***.com/questions/42376972/…。我很确定 import "rxjs" 要么什么都不做,要么做“很多”;) 如果用户决定使用除Observable 之外的其他功能,我删除了最佳实践部分并添加了rxjs。由用户决定是否包含它。即BehaviorSubject【参考方案2】:
import  Observable  from 'rxjs/Observable';
import  Injectable  from '@angular/core';
import  Http, URLSearchParams  from '@angular/http';

export interface SomeInterface 
   // Define the properties of the JSON object sent as response from the backend


@Injectable()
export class SomeService 
   constructor(private _http: Http)

   queryElements(ids: string[] = [], pageSize = 25): Observable<SomeInterface>
      const params = new URLSearchParams();
      params.set('perPage', pageSize); // using set: replace the existing value of the query parameter "perPage" if exist.
      ids.forEach(id => params.append('collectionId', id)); // using append: allows multiple values for the query parameter "collectionId" 
      return 
       this._http.get("http://address/cards/topbrand",params: params)
         .map(r => r.json())
         .catch(//handle error);
   

【讨论】:

以上是关于基于数组 Angular 2 中 id 数量的动态 URL 参数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 中使用多个 ViewChild 元素 (2/4)

如何在 Angular 中将动态 JSON 对象数组导出为 CSV?

在 Angular 2/4 中使用 typescript 动态创建 HTML 元素数组

表单未预先填充Angular 8

SQL选择动态记录数

Angular 4 中的可配置组件(动态类加载器)