Как отфильтровать значения моего Observable? - PullRequest
0 голосов
/ 25 марта 2019

Я узнаю о наблюдаемых атм и у меня есть вопрос.Я получаю массив json из моего бэкэнда API и помещаю его в Observable (где изображение - моя собственная определенная модель).Теперь это все изображения, но я хочу только те, чье имя начинается с дисплея.Я попробовал несколько вещей, но я не могу найти решение.Это то, что я получил до сих пор.

  get images$(): Observable<Image[]> {
    return this._fetchImages$
      .pipe(
        filter(i => i.filter(img => img.name.toLowerCase().startsWith("display")))
      );
  }

это дает: Type 'Image[]' is not assignable to type 'boolean'.ts(2322) filter.d.ts(3, 46): The expected type comes from the return type of this signature.

Класс модели изображения

export class Image {
  constructor(
    private _name: string,
    private _iso: string,
    private _shutter: string,
    private _aperture: string,
    private _country: string,
    private _likes: number,
    private _content: string
  ) {}

  get name(): string {
    return this._name;
  }

  get iso(): string {
    return this._iso;
  }

  get shutter(): string {
    return this._shutter;
  }

  get aperture(): string {
    return this._aperture;
  }

  get country(): string {
    return this._country;
  }

  get likes(): number {
    return this._likes;
  }

  get content(): string {
    return this._content;
  }

  set likes(value: number) {
    this._likes = value;
  }

  static fromJson(json: any): Image {
    return new Image(
      json.name,
      json.iso,
      json.shutterSpeed,
      json.aperture,
      json.country,
      json.likes,
      json.content
    );
  }
}

Сервис, который предоставляет мнезначения

export class ImageDataService {
  constructor(private http: HttpClient) {}

  get images$(): Observable<Image[]> {
    return this.http
      .get(`${environment.apiUrl}/images/`)
      .pipe(map((list: any[]): Image[] => list.map(Image.fromJson)));
  }
}

компонент, который запрашивает наблюдаемый

export class GridComponent implements OnInit {
  public countryFilter: string;
  public filterImage$ = new Subject<string>();
  private _fetchImages$: Observable<Image[]> = this._imageDataService.images$;

  constructor(private _imageDataService: ImageDataService) {
    this.filterImage$
      .pipe(
        distinctUntilChanged(),
        debounceTime(400),
        map(val => val.toLowerCase())
      )
      .subscribe(val => (this.countryFilter = val));
  }

  get images$(): Observable<Image[]> {
    return this._fetchImages$.pipe(
      map(i => i.filter(img => img.name.toLowerCase().startsWith('display')))
    );
  }

  ngOnInit() {}
}
<div>
  <mat-form-field>
    <input matInput placeholder="Country" type="text" #countryName (keyup)="filterImage$.next($event.target.value)"
      class="browser-default">
  </mat-form-field>
  <mat-grid-list cols="3" gutterSize=" 5px" rowHeight="500px">
    <mat-grid-tile *ngFor="let image of (images$ | async)">
      <app-image [image]="image"></app-image>
    </mat-grid-tile>
  </mat-grid-list>
</div>

export class ImageComponent implements OnInit {
  private _icon: string;
  @Input('image') public image: Image;

  constructor() {
    this._icon = 'favorite_border';
  }

  ngOnInit() {}

  like() {
    if (this._icon === 'favorite_border') {
      this._icon = 'favorite';
      this.likes++;
    } else {
      this._icon = 'favorite_border';
      this.image.likes--;
    }
    console.log(this._icon);
  }

  get icon(): string {
    return this._icon;
  }

  set icon(value: string) {
    this._icon = value;
  }

  get iso(): string {
    return this.image.iso;
  }

  get aperture(): string {
    return this.image.aperture;
  }

  get shutterspeed(): string {
    return this.image.shutter;
  }

  get country(): string {
    return this.image.country;
  }

  get name(): string {
    return this.image.name;
  }

  get content(): string {
    return this.image.content;
  }

  get likes(): number {
    return this.image.likes;
  }

  set likes(value: number) {
    this.image.likes = value;
  }
}

Я получаю 10 json-объектов, отправленных мне:

{
  "id": 1,
  "name": "Header",
  "iso": "ISO-200",
  "shutterSpeed": "1/80 sec",
  "aperture": "f/5.6",
  "country": "Belgium",
  "content": //a base64 string
}
{
  "id": 2,
  "name": "Parallax1",
  "iso": "ISO-100",
  "shutterSpeed": "1/200 sec",
  "aperture": "f/10",
  "country": "Italy",
  "content": another base64 string
}
{
  "id": 5,
  "name": "Display1",
  "iso": "ISO-100",
  "shutterSpeed": "1/200 sec",
  "aperture": "f/10",
  "country": "Italy",
  "content": another base64 string
}

Теперь основным отличием изображений является название: у меня 1 заголовок, 3 параллакса и 6 отображаемых изображений.Теперь я хочу отфильтровать то, что я получаю только изображения дисплея.В основном: 10 изображений приходят ---> 6 выходят

С уважением

Ответы [ 2 ]

0 голосов
/ 30 марта 2019

Я переместил отображение в класс, где я получаю их, используя HttpClient вместо того, чтобы пытаться отфильтровать их в моем компоненте.Теперь он работает без строки запроса.

код:

export class ImageDataService {
  constructor(private http: HttpClient) {}

  get images$(): Observable<Image[]> {
    return this.http
      .get(`${environment.apiUrl}/images/`)
      .pipe(
        map((list: any[]): Image[] => list.map(Image.fromJson)),
        map(imgs =>
          imgs.filter(img => img.name.toLowerCase().startsWith('display'))
        )
      );
  }
}
0 голосов
/ 25 марта 2019

Я думаю, вы должны изменить filter на map, например:

.pipe(
    map(
        i => i.filter(
            img => img.name.toLowerCase().startsWith("display")
        )
    )
);
...