有效过滤一组可观察物

时间:2019-05-08 17:31:09

标签: angular rxjs rxjs6

我正在学习官方的角度教程(https://angular.io/tutorial/toh-pt4)。请问我的低水平:(

我正在尝试修改一个返回英雄列表的服务...作为rxjs的可观察对象,因为这是最有效的方法

hero.service.ts
==============

import {Injectable} from '@ angular / core';

import {Observable, of} from 'rxjs';

import {Hero} from './hero';
import {HEROES} from './mock-heroes';
import {MessageService} from './message.service';

@Injectable ({
  providedIn: 'root',
})
export class HeroService {

  constructor (private messageService: MessageService) {}

  getHeroes (): Observable <Hero []> {
    // TODO: send the message _after_ fetching the heroes
    this.messageService.add ('HeroService: fetched heroes');
    return of (HEROES);
  }
}

mock-heroes
===========

import {Hero} from './hero';

export const HEROES: Hero [] = [
  {id: 11, name: 'Mr. Nice '},
  {id: 12, name: 'Narco'},
  {id: 13, name: 'Bombast'},
  {id: 14, name: 'Celeritas'},
  {id: 15, name: 'Magneta'},
  {id: 16, name: 'RubberMan'},
  {id: 17, name: 'Dynama'},
  {id: 18, name: 'Dr IQ'},
  {id: 19, name: 'Magma'},
  {id: 20, name: 'Tornado'}
];

我想提供一种在传递ID时仅返回英雄的服务

import {Injectable} from '@ angular / core';
import {Hero} from './hero';
import {HEROES} from './mock-heroes';
import {Observable, of} from 'rxjs';
import {MessageService} from './message.service';
import {map} from 'rxjs / operators';

@Injectable ({
  providedIn: 'root'
})
export class HeroService {

  private heroes: Observable <Hero []>;

  getHeroes (): Observable <Hero []> {
    this.messageService.add ('HeroService: fetched heroes');
    // return of (HEROES);
    this.heroes = of (HEROES);
    return this.heroes;
  }

  getHeroeById (id: number): Observable <Hero> {
    this.messageService.add ('A hero is queried with id' + id);
    

    return this.heroes.pipe (map (x => x.id === id));
  }

  constructor (private messageService: MessageService) {}

 / * getHeroes (): Hero [] {
    return HEROES;
  } * /

  //builder() { }
}

src / app / hero.service.ts中的错误(26,5):错误TS2322:类型'Observable'不能分配给类型'Observable'。 “布尔”类型不能分配给“英雄”类型。 src / app / hero.service.ts(26.40):TS2339错误:类型“英雄[]”上不存在属性“ id”。

你能帮我吗?

3 个答案:

答案 0 :(得分:2)

您有两种选择。您可以使用Array.find()或Array.filter()

Array.filter()

getHeroeById (id: number): Observable <Hero> {
  this.messageService.add('A hero is queried with id: ' + id);

  // Filter heroes to get heroById
  return this.heroes.filter(x => x.id == id)[0];
}

Array.find()

getHeroeById (id: number): Observable <Hero> {
  this.messageService.add('A hero is queried with id: ' + id);

  // Find hero by Id.
  return this.heroes.find(x => x.id == this.personId);
}

答案 1 :(得分:1)

您要返回英雄列表中具有匹配ID的英雄,请尝试替换

return this.heroes.pipe (map (x => x.id === id));

作者

return this.heroes.pipe (map (heroes => heroes.find( hero => hero.id === id));

答案 2 :(得分:1)

您的问题是此行:

return this.heroes.pipe (map (x => x.id === id));

您正在使用rx map运算符,该运算符对流中的项目进行操作并对其进行转换,并且在这种情况下,流项目是英雄的实际数组。您将返回该数组的某些不存在的id属性是否等于id参数(该值为布尔值)的测试结果。这就是为什么看到错误的原因。

在这种情况下,应在流中对数组使用数组查找运算符,因为要在数组中查找该项,就像这样:

return this.heroes.pipe (map (heroes => heroes.find(h => h.id === id)));

这样,您将在rx映射转换操作中返回数组查找操作的实际结果。

接下来,在调用heroes之前,您不会初始化getHeroes()可观察对象。这可能是故意的,但似乎您应该改为在构造函数中执行此操作,以便可以首先安全地调用getHeroeById()