【问题标题】:Where did this switchmap's argument come from?这个 switchmap 的论点从何而来?
【发布时间】:2018-08-13 23:07:22
【问题描述】:

我目前正在关注 Jogesh Muppala 在 Coursera 上的 Angular 课程,问题在于以下代码行。

   this.route.params.pipe(switchMap((params: Params) => this.dishService.getDish(+params['id'])))

其余代码如下。到目前为止,我的理解是 this.route.params 是一个 Observable,并且 this.dishService.getDish(+params[id]) 也将返回一个 Observable。我的问题是了解 (params: Params) 是如何到达那里的。它用作箭头函数中的参数,并且在语句末尾附近被 getDish 函数使用。但是,在行的开头,我们只能通过 this.route.params 访问 params。它是不同的参数吗?类型声明 params: Params 使它看起来像是一个全新的 Params 类型实例。但是如果是这样,getDish怎么会使用它呢?

import { Component, OnInit} from '@angular/core';
import {Params, ActivatedRoute} from '@angular/router';
import {Location} from '@angular/common';
import{ Dish} from '../shared/dish';
import { DishService} from '../services/dish.service';
import { switchMap } from 'rxjs/operators';

@Component({
  selector: 'app-dishdetail',
  templateUrl: './dishdetail.component.html',
  styleUrls: ['./dishdetail.component.scss']
})
export class DishdetailComponent implements OnInit {

  dish: Dish;
  dishIds: number[];
  prev: number;
  next: number;


  constructor(private dishService: DishService, private route: ActivatedRoute,
    private location: Location) { 

  }

  ngOnInit() {
    this.dishService.getDishIds().subscribe(dishIds => this.dishIds = dishIds);
    this.route.params.pipe(switchMap((params: Params) => this.dishService.getDish(+params['id'])))
    .subscribe(dish => { this.dish = dish; this.setPrevNext(dish.id); });
  }

  setPrevNext(dishId: number) {
    const index = this.dishIds.indexOf(dishId);
    this.prev = this.dishIds[(this.dishIds.length + index - 1) % this.dishIds.length];
    this.next = this.dishIds[(this.dishIds.length + index + 1) % this.dishIds.length];
  }


  goBack(): void{
      this.location.back();
  }

}

感谢您的阅读。

【问题讨论】:

    标签: angular rxjs angular2-observables


    【解决方案1】:

    (params: Params) 来自router.params,它是 rxjs 6 进行可观察运算符链的方式。

    本质上真正发生的是.pipe 获取函数列表,并且列表中的每个函数都获取前一个函数的值,除非它前面有tapfilter 等...

    所以

    this.route.params.pipe(switchMap((params: Params) => this.dishService.getDish(+params['id'])))
    

    之前是这样写的

    this.route.params.switchMap((params: Params) => this.dishService.getDish(+params['id']))
    

    所以它会从 route.params 获取值,并将其传递给 switchMap 运算符,该运算符将返回您传递给它的函数结果的新 Observable

    【讨论】:

    • 但是 Angular 如何在不使用 this.route.params 所需的点表示法的情况下获取 param: Params,以及它为什么要声明 params 类型?
    • 这比 Angular 更像是一种打字稿语法。函数组合和箭头函数语法糖你可以看看:codecraft.tv/courses/angular/es6-typescript/arrow 或者basarat.gitbooks.io/typescript/docs/arrow-functions.html
    • 我想我理解箭头符号,我不清楚的是如何在不使用点符号的情况下在箭头函数的标题中访问参数。
    • 它从.pipe 传入switchMapParams 只是变量的声明
    • 所以我们不必通过点符号访问参数的原因是因为管道提供了上下文?我知道 Params 是在声明一个变量,但我认为 params 已经存在,所以我不清楚为什么要声明它。
    【解决方案2】:

    有点像这样:

    const bmw = {
      type: car,
      attributes: {
        color: 'red',
        year: 2000
      }
    }
    
    const attributes = bmw.attributes;
    

    我们碰巧用同名attributes 命名了两个不同的事物:一个是变量,另一个是对象中的属性。除了不幸的同名巧合之外,他们没有任何血缘关系。

    在您的情况下,在this.route.params 中,params 是this.route 中的一个属性,它返回一个 Observable。

    (params: Params) => this.dishService... 是一个匿名函数,与编写(function anon(params: Params) { this.dishService... }).bind(this) 相同。这里,params 是函数接收的参数的名称。

    上述函数在this.routes.params 的 Observable 上发出新值时执行。此处发出的值作为其参数传递给匿名函数,该函数恰好称为params。所以它不需要点符号,因为它指的不是同一件事:它指的是来自 Observable 的值。

    尽管匿名函数(箭头函数)是一个通过switchMap 传递的函数,但它的根部对于放在源 Observable(this.route.params)上的每个值都会执行一次。每次执行时,switchMap 都会将 Observable 中的当前值作为第一个参数 params 传入。 SwitchMap 期望这个函数返回一个新的 Observable,这是 this.dishService.getDish 返回的。

    HTH

    【讨论】:

      猜你喜欢
      • 2015-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-03
      • 1970-01-01
      • 2019-11-12
      • 2011-11-26
      • 1970-01-01
      相关资源
      最近更新 更多