web-dev-qa-db-ja.com

http getで複雑なオブジェクトを処理するAngular 6

サブスクライブするオブジェクトの処理方法がわかりません。オブジェクトは次の構造です。

{
  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);
          });

動作しません。その結果、「プロパティ 'items'はタイプ 'VideoListModel []'に存在しません」というエラーが発生します。直感的には、問題がインターフェースにある可能性が最も高いことを理解していますが、フィルタリングが正しく機能するようにインターフェースを変更する方法を理解できません。誰かが複雑なオブジェクトのフィルタリングに遭遇した場合は、この問題の解決方法を教えてください。

3
Artemy Khodorev

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;
}
1
Piero

dataはタイプarrayVideoListModelであると言い、原因の配列にはプロパティ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();

さらに、angular version 4+を使用する場合は、このようにデータをマッピングします

getVideoTape() {
    return this.http.get<VideoListModel[]>(`http://ip_adress/api/v1/mixed_galleries/1`);
}
1
Fussel

@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`);
    }
}
0
Prabhat Maurya