这个 switchmap 的参数从何而来?

Where did this switchmap's argument come from?

我目前正在关注 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]) 也将 return 一个 Observable。我的问题是了解 (params: Params) 是如何到达那里的。它用作箭头函数中的参数,并在语句末尾附近由 getDish 函数使用。但是,在该行的开头,我们只能通过 this.route.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();
  }

}

感谢阅读。

(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 运算符,这将 return 一个新的 Observable 来自您的函数的结果传进去了。

有点像这样:

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

const attributes = bmw.attributes;

我们恰好将两个不同的东西同名命名attributes:一个是变量,一个是对象中的属性。除了不幸的巧合同名外,他们没有任何关系。

在你的例子中,在 this.route.params 中,params 是 this.route 中的一个 属性,它 return 是一个 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 期望此函数 return 给它一个新的 Observable,这是由 this.dishService.getDish.

编辑的 return

HTH