5

我不明白如何处理我订阅的对象。对象结构如下:

{
  data:{
       date: "2018-02-20 13:10:23",
       text: "Описание",
       id: 1,
       items: [
              0: {
                 date: "2018-02-20 13:10:23",
                 text: "Описание",
                 images: [
                         0: "image1.jpg",
                         1: "image2.jpg"
                         ],
                 name: "Изображения",
                 type: "images"
                 },
              1: {
                 date: "2018-02-20 13:10:23",
                 text: "Описание",
                 image: null,
                 type: "video",
                 url: "https://www.youtube.com/embed/v64KOxKVLVg"
                 }
              ]
       }
}

我通过以下服务提出上诉:

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
@Injectable()
export class VideoService {
    constructor(private http: HttpClient) {}

    getVideoTape() {
        return this.http.get(`http://ip_adress/api/v1/mixed_galleries/1`);
    }
}

有一个接口模型:

export class VideoListModel {
    constructor(
        public created_at: string,
        public description: string,
        public id: number,
        public items: any[],
        public name: string
    ) {}
}

我在组件中进行处理:

import {Component, OnDestroy, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs';
import {filter} from 'rxjs/operators';
import {VideoService} from '../shared/services/video.service';
import {VideoListModel} from '../../shared/models/video-list.model';

@Component({
  selector: 'app-video-index',
  templateUrl: './video-index.component.html',
  styleUrls: ['./video-index.component.scss']
})

export class VideoIndexComponent implements OnInit, OnDestroy {
    private videoTape = [];
    private _subscription2: Subscription;

    constructor( private videoService: VideoService ) { }

  ngOnInit() {
      this._subscription2 = this.videoService.getVideoTape()
          .subscribe((data: VideoListModel[]) => {
          this.videoTape = data;
          console.log(this.videoTape);
      });
  }

    ngOnDestroy() {
        this._subscription2.unsubscribe();
    }

}

任务是按类型从对象中进行选择:“视频”。通过 AJAX + jQuery 没有问题,在 Angular 中我比较新。昨天铲了一堆视频课程,但没有过滤这种复杂对象的例子。

建造:

this._subscription2 = this.videoService.getVideoTape()
          .pipe(filter((data: VideoListModel[]) => data.items.type === 'video'))
          .subscribe((data: any) => {
              this.videoTape = data.data;
              console.log(this.videoTape);
          });

不起作用。结果是一个错误,提示“类型'VideoListModel []'上不存在属性'项目'”。直觉上,我知道问题很可能在界面中,但我无法理解如何修改界面以使过滤正常工作。如果有人遇到过滤复杂对象,请告诉我如何解决这个问题。

4

4 回答 4

3

您没有一个 VideoModels 数组,而是items一个对象中的数组。将整个内容传送到过滤器可以让您从数组中过滤项目,但您有一个对象。您可以尝试以下解决方法:

创建这样的界面

interface Item {
  date: Date;
  text: string;
  images: string[];
  name: string;
  type: string;
}

export interface VideoModel {
  data: {
    date: Date;
    text: string;
    id: number;
    items: Item[];
  }
}

然后你可以在你的服务中使用 HttpClient 如下

import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
[...]

getVideoTape(): Observable<VideoModel> {
  return this.http.get<VideoModel>(url).pipe(
    map(model => {
      const items = model.data.items.filter(item => item.type === 'video');
      model.data.items = items;
      return model;
    }),
    catchError(error => console.error(error))
  );
}

请注意您的图像数组,因为它不是有效的 json, string[]? 过滤服务器端的类型以减少流量不是更好吗?

于 2018-05-25T08:44:28.627 回答
1

你说那data是一个array类型VideoListModel,原因的数组没有属性items。你所做的就像Array.items.type没有意义一样。可能有更多奇特的解决方案,但尝试将您的结果数组映射到可以使用过滤器的可观察对象。

this._subscription2 = this.videoService.getVideoTape()
.pipe(
    map(data => from(data).pipe(filter((d: VideoListModel) => d.items.type === 'video')))
    tap(data => data.subscribe(d => {
        this.videoTape.push(d);
    }))
).subscribe();

另外在使用角度版本 4+ 时像这样映射您的数据

getVideoTape() {
    return this.http.get<VideoListModel[]>(`http://ip_adress/api/v1/mixed_galleries/1`);
}
于 2018-05-25T08:48:42.597 回答
1

您的 json 数据无效。

它应该是

{
"data":{
     "date": "2018-02-20 13:10:23",
     "text": "tt",
     "id": 1,
     "items": [
            {
               "date": "2018-02-20 13:10:23",
               "text": "Описание",
               "images": [
                       "image1.jpg",
                       "image2.jpg"
                       ],
               "name": "Изображения",
               "type": "images"
               },
            {
               "date": "2018-02-20 13:10:23",
               "text": "Описание",
               "image": null,
               "type": "video",
               "url": "https://www.youtube.com/embed/v64KOxKVLVg"
               }
            ]
     }
}

然后去http://json2ts.com/

你的模型是

export interface Item {
    date: string;
    text: string;
    images: string[];
    name: string;
    type: string;
    image?: any;
    url: string;
}

export interface Data {
    date: string;
    text: string;
    id: number;
    items: Item[];
}

export interface VideotapeAnswer {
    data: Data;
}
于 2018-05-25T08:39:15.823 回答
0

包括@Piero 建议的更改,您的服务不会返回任何可观察的。

import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
@Injectable()
export class VideoService {
    constructor(private http: HttpClient) {}

    getVideoTape():Observable<any>  {
        return this.http.get(`http://ip_adress/api/v1/mixed_galleries/1`);
    }
}
于 2018-05-25T08:50:11.477 回答