【问题标题】:Why HttpParams doesn't work in multiple line in angular 4.3为什么 HttpParams 在 Angular 4.3 中的多行中不起作用
【发布时间】:2018-01-09 14:27:01
【问题描述】:

从 Angular 4.3 开始,他们引入了 HttpClient 而不是 Http。 在HttpClient 我不能使用URLSearchParams 作为url 查询参数。而不是URLSearchParams,我使用的是HttpParams

这个作品

 var params = new HttpParams().append('a', '1').append('b', '2');

但是为什么这不起作用

var params = new HttpParams();
params.append('a', '1');
params.append('b', '2');

【问题讨论】:

    标签: angular


    【解决方案1】:

    新的 HTTP 客户端使用不可变的请求对象及其所有一致部分,例如 HttpParamsHttpHeaders。要了解为什么请参阅Why is http request and all its constituent parts like HttpHeaders and HttpParams are immutable 或阅读文章Insider’s guide into interceptors and HttpClient mechanics in Angular

    这就是为什么append 方法会在每次调用append 时合并参数并返回合并的HttpParams 对象的新实例

      /**
       * Construct a new body with an appended value for the given parameter name.
       */
      append(param: string, value: string): HttpParams { 
            return this.clone({param, value, op: 'a'}); 
      }
    
      private clone(update: Update): HttpParams {
        const clone = new HttpParams({encoder: this.encoder}); <-------
        clone.cloneFrom = this.cloneFrom || this;
        clone.updates = (this.updates || []).concat([update]);
        return clone;                                          <--------
      }
    

    所以这里:

    var params = new HttpParams().append('a', '1').append('b', '2');
    

    appendb 参数更新由 appenda 参数返回的对象。

    虽然采用这种方法

    var params = new HttpParams();
    params.append('a', '1');
    params.append('b', '2');
    

    append 始终更新HttpParams 的初始状态,所有中间append 操作实际上被忽略。

    所以你必须使用之前的返回值:

    var params = new HttpParams();
    params = params.append('a', '1');
    params = params.append('b', '2');
    

    或者使用fromObject的快捷方式:

    let searchParams = new HttpParams({
        fromObject: {
            query: query,
            sort: sort,
            order: order
        }
    });
    
    const modified = req.clone({params: searchParams});
    

    或者直接对请求使用setParams方法:

    const modified = req.clone({setParams: {'query': query, 'sort': sort, 'order': order}});
    

    此外,从 5.1.x 开始,您可以直接传递对象而不是 HttpParams 的实例:

    const params = {
      'a': '1',
      'b': '2'
    };
    
    this.http.get('...', { params })
    

    【讨论】:

    • 谢谢。如果我不怎么修改我的params。假设如果我有c 那么我该如何修改params 对象如果我必须重建我的params 我认为这不是好方法。
    • 抱歉,听不懂。你能改写一下吗?
    • @imran 我认为你可以使用 params.set("key", 1).set("key", 2);这样键将留下 2.
    • 这种接缝也适用于 params = params.set('a', '1');正如我刚刚发现的那样(角度 5);
    • @SoEzPz,是的,在新的 HttpClient 模块中,大多数实体都是不可变的
    【解决方案2】:

    为了这个工作

    var params = new HttpParams();
    params.append('a', '1');
    params.append('b', '2');
    

    这个必须改成

    var params = new HttpParams();
    params = params.append('a', '1');
    params = params.append('b', '2');
    

    可以循环动态添加

    【讨论】:

    • 这是唯一适用于 Angular 5 的解决方案。非常感谢你
    • 正如 Pratap A.K 所说,这对我来说只是可行的解决方案。我必须添加重复的参数,例如 {category:1,category:3}
    • 这太反直觉了..但它有效..谢谢
    【解决方案3】:

    5.0.0-beta.6 (2017-09-03)推出新功能(accept object map for HttpClient headers & params)。

    现在我们可以直接传递对象而不是HttpParams

    const params = {
      'a': '1',
      'b': '2'
    };
    
    this.http.get('...', { params })
    

    或者代替HttpHeaders:

    http.get('/url', {
       headers: {'My-Header': 'header value'}
    })
    

    【讨论】:

      【解决方案4】:

      实际上@Maximus 对HttpParams 对象的不变性 做了很好的解释,您只需将params 替换为其在循环中的克隆。

      假设您有零对多 params 可用,存储在类似于以下结构的数组中:

      "params": [
        {
          "key": "p1",
          "value": "v1"
        },
        {
          "key": "p2",
          "value": "v2"
        }
      ]
      

      根据上面的信息,下面的辅助函数应该会有所帮助:

      export const getHttpParams = (params: Array<any>): HttpParams => {
        let res = new HttpParams();
      
        for (const item of params)
          res = res.append(item.key, item.value);
      
        return res;
      };
      

      用法

      const backend = 'http://httpstat.us/200';
      const params = getHttpParams(backend.params);
      
      return this.http.get(`${backend}`, { params });
      

      希望对你有帮助!

      【讨论】:

        【解决方案5】:

        我在这篇文章中尝试了所有其他方法,但收效甚微。因此,我将参数链接到 HttpParams 单例并调用 toString() 以返回 string 类型。然后我可以将它传递给http.get(),并且对于构建 url 参数来说,一切似乎都很好。这是我的ng -v

        $ ng -v
            _                      _                 ____ _     ___
           / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
          / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
         / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
        /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                   |___/
        @angular/cli: 1.4.2
        node: 8.5.0
        os: linux x64
        @angular/animations: 4.4.3
        @angular/cdk: 2.0.0-beta.10
        @angular/common: 4.4.3
        @angular/compiler: 4.4.3
        @angular/core: 4.4.3
        @angular/forms: 4.4.3
        @angular/http: 4.4.3
        @angular/material: 2.0.0-beta.10
        @angular/platform-browser: 4.4.3
        @angular/platform-browser-dynamic: 4.4.3
        @angular/router: 4.4.3
        @angular/cli: 1.4.2
        @angular/compiler-cli: 4.4.3
        @angular/language-service: 4.4.3
        typescript: 2.3.4
        

        这是一个对我很有效的例子:

        // Simplified for example (I'm using Redux and won't go into all that)
        private downloadState = { requestType: 'Auction', fileType: 'CSV' };
        
        getStuffFromApi(): Observable<any> {
            const { requestType, fileType } = this.downloadState;
            const apiRoot = 'http://www.example.com';
        
            const params: string = new HttpParams()
                .set('RequestType', requestType)
                .set('FileType', fileType)
                .set('AuctionType', auctionType)
                .set('BackorderDay', backorderDay)
                .toString();
        
            return this.http.get(apiRoot, { params })
                .map(res => res.json())
                .catch(err => Observable.of(err.json()));
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-18
          • 2019-12-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-15
          • 2022-01-18
          • 1970-01-01
          相关资源
          最近更新 更多