【问题标题】:How do you declare a GET call with parameters?如何声明带参数的 GET 调用?
【发布时间】:2021-08-03 07:33:56
【问题描述】:

从 API 获取数据的一种技术是在服务中这样声明它:

getItems$ = this.httpClient.get<Item[]>(this.url);

然后订阅它或在消费组件中使用异步。

如果get调用需要get by id之类的参数,你会怎么做?

编辑:以上是使用 RxJS 流的声明性方法的示例。 getItems$ 是一个属性。

所以问题是,当使用带有 property 定义流而不是调用 getItems(itemId) 方法的声明性方法时,如何传入参数?

【问题讨论】:

    标签: angular rxjs angular-httpclient rxjs-observables


    【解决方案1】:

    要处理任何“参数”,您可以使用 Subject 或 BehaviorSubject 创建另一个操作流。然后将“参数”发送到流中。

    这是我的一个应用程序的示例。

      // Handle product selection action
      private productSelectedSubject = new BehaviorSubject<number>(0);
      productSelectedAction$ = this.productSelectedSubject.asObservable();
    
      product$ = this.productSelectedAction$
        .pipe(
          filter(id => !!id),
          switchMap(selectedProductId =>
            this.http.get<Product>(`${this.productsUrl}/${selectedProductId}`)
          ));
    
      // Selected product was changed
      changeSelectedProduct(selectedProductId: number): void {
        this.productSelectedSubject.next(selectedProductId);
      }
    

    这里我们创建一个初始值为 0 的 BehaviorSubject。(您可以使用没有初始值的 Subject。)

    当用户选择一个产品(或确定具体产品)时,该产品的 id 被发送到productSelectedSubject

    然后,每次有新产品 ID 发送到流中时,此代码都会使用管道做出反应。管道中的第一个运算符过滤掉任何无效的 Id。然后 switchMap 使用发出的产品 ID 来发出 http get。

    我有一个完整的例子,它还在这里设置了额外的分页“参数”:https://github.com/DeborahK/Angular-ActionStreams

    【讨论】:

      【解决方案2】:

      我喜欢你的问题。我也总是尝试以声明的方式定义我的 observables。然而,当涉及带参数的方法时(尤其是在 Angular 服务中),我倾向于只使用返回 observables 的仅使用函数:

      class ItemService {
        public getItem(id: string) {
          return this.http.get<Item>(`${this.apiRoot}/items/${id}`);  
        }
      }
      

      如果服务本身负责管理这些“参数”的状态,那么使用 @DeborahK 提到的主题为消费者提供传递值的工具是有意义的。

      但是,如果组件负责这些参数,那么通常不需要有 Subjects,因为这些参数值通常来自其他可观察的来源,例如反应式表单控件或路由参数。

      例如:

      class ItemComponent {
        private id$ = this.route.paramMap.pipe(params => params.get('id'));
      
        public item$ = this.id$.pipe(
          switchMap(id => this.itemService.getItem(id))
        );
        
        constructor(
          private route: ActivatedRoute,  
          private itemService: ItemService
        ) { }
      }
      

      在组件中注意,item$ 仍然以您喜欢的声明方式定义。另请注意,我做了@DeborahK 提到的事情并从另一个流中定义它(另一个流恰好是不同的可观察对象,而不是主题)。

      【讨论】:

        【解决方案3】:

        这取决于您请求的 http api。 由于 get 请求没有正文,因此通常将参数添加到 url,如下所示: http://example.com/customer?id=25

        HttpClient的get、post、put等方法有第二个options参数,可以有HttpParams类型的params属性,可以在其中设置参数 data$ = this.http.get&lt;item[]&gt;(this.url,{params: new HttpParams().set('id',25)}) `

        这将处理添加到实际请求的 url。

        【讨论】:

          猜你喜欢
          • 2010-09-16
          • 2012-06-09
          • 2019-11-03
          • 2014-12-31
          • 1970-01-01
          • 1970-01-01
          • 2019-03-17
          • 1970-01-01
          相关资源
          最近更新 更多