Angular 6通过ID从嵌套数组获取对象

时间:2018-08-05 12:19:34

标签: angular typescript nested find components

我有包含课程的课程数组,每个课程都包含细分数组。我的课程详细信息部分中有特定的课程,我想按ID来获得一个细分。

示例:我有这门课程:

course: ICourse;

course = {
    "data": [
        "id": 1,
        "title": "Introduction",
        "author": "Ofir",
        "segments": [
          { "id": 1, "name": "lesson 1", "segment_type": "video", "data:" "www.hey.com/1" },
          { "id": 2, "name": "lesson 2", "segment_type": "video", "data:" "www.hey.com/1" },
          { "id": 3, "name": "lesson 3", "segment_type": "video", "data:" "www.hey.com/1" },
          { "id": 4, "name": "quiz 1", "segment_type": "quiz1", "questions": [
                                                                   {"id":1, "name":"q1"}] },
        ]
    ]
}

编辑:click here,以查看我从服务器获取的JSON响应

,我的段ID为4。我想要的是一种获取段对象的方法。这是我到目前为止所做的(它不起作用并且没有显示错误):

course.ts

export interface ICourse {
  id: number;
  title: string;
  autor: string;
  segments: ISegment[];
}

export interface ISegment {
  id: number;
  unit_id: number;
  unit_title: string;
  name: string;
  type: string;
  data: string;
  questions: IQuestion[];
}

export interface IQuestion {
  id: number;
  question: string;
  answer1: string;
  answer2: string;
  answer3: string;
  answer4: string;
  correct: number;
}

course-play.component

import { Component, OnInit, Input} from '@angular/core';
import { ActivatedRoute, Router, Routes, NavigationEnd } from '@angular/router';
import { MatSidenavModule } from '@angular/material/sidenav';
import { LocalStorage } from '@ngx-pwa/local-storage';

import { ICourse } from '../course';
import { CourseService } from '../course.service';


// Couse-play decorator
@Component({
  selector: 'lg-course-play-course-play',
  templateUrl: './course-play.component.html',
  styleUrls: ['./course-play.component.sass']
})

export class CoursePlayComponent implements OnInit {
  errorMessage: string;
  course: ICourse;
  courseId: number;
  public currentSegment: ISegment;

  constructor(private courseService: CourseService,
      private route: ActivatedRoute,
      private router: Router) {
         courseService.courseId$.subscribe( courseId => {
           this.courseId = courseId;
         })
    }

    // On start of the life cycle
    ngOnInit() {
        // save this course id from course-detail and get http request from the service
        this.courseId = JSON.parse(localStorage.getItem("courseId"))
        this.getCourse(this.courseId);

        // get the current segment id to use it on the html file
        //const id = +this.route.snapshot.paramMap.get('id');
        //getCurrentSegment(id);

        console.log(this.currentSegment.id);
      }

      // Get course detail by id
      getCourse(id: number) {
          this.courseService.getCourse(id).subscribe(
            course => this.course = course,
            error  => this.errorMessage = <any>error,
            const id = +this.route.snapshot.paramMap.get('id'),
            getCurrentSegment(id)
          );
        }

      // search in course single segment by id and save it in currentSegment
      // to use it in the html file
      getCurrentSegment(id: number){
          this.currentSegment = this.course.segments.find(d => d.id === id);
      }
}

html文件 and this is the screenshot of the webpage

  <div class="row content" *ngIf="course">
    <!-- Side nav-bar -->
    <div class="col-md-3">
      <!-- Image Logo -->
      <div id="head_sidebar">
        <img src="./assets/images/lg-white.png" class="d-inline-block align-top logo" alt="" routerLink="/courses" style="outline: none">
        <h3>{{course.title}}</h3>
      </div>

      <div class="col-md-12 sidenav">
        <!-- Menu elemets -->
        <div class="nav nav-pills nav-stacked" *ngFor="let unit of course.segments | groupBy: 'unit_title'; let i = index">
          <h6 class="course_play_title">Unit {{ i+1 }}: {{ unit.key }} </h6>
          <ul *ngFor="let lesson of unit.value">
            <li class="course_play_item">
              <a class="nav-link" routerLink="/courses/{{course.id}}/segments/{{lesson.id}}" (click)=getCurrentSegment(lesson.id)>{{lesson.name}} </a>
            </li>
          </ul>
          <br>
        </div>
      </div>
    </div>

    <!-- Body -->
    <div class="col-md-9 no-gutters" *ngIf="currentSegment">
      <div class="col-md-12 course_play_body text-center" id="#lesson">
        <h1>{{currentSegment.name}}</h1>
        <p class='sub-text' *ngIf="course.segments?.length > 0">lesson {{currentSegment.id}} of {{course.segments?.length}}</p>
        <hr>
        <iframe *ngIf="currentSegment.segment_type === 'Video'" frameborder="0" allowfullscreen="true" src="{{currentSegment.data}}"></iframe>
        <!-- <iframe frameborder="0" allowfullscreen="true" src="{{segment.data}}"></iframe> -->
      </div>
    </div>

  </div>

1 个答案:

答案 0 :(得分:1)

JSON是无效的,但我假设data是一个对象,而不是数组。

您可以使用数组的find函数来查找匹配的第一个元素。

在这种情况下,我们使用(c) => c.id === 4创建一个返回true的函数,一旦找到ID等于4的项

let course = {
    "data": {
        "id": 1,
        "title": "Introduction",
        "author": "Ofir",
        "segments": [
          { "id": 1, "name": "lesson 1", "segment_type": "video", "data": "www.hey.com/1" },
          { "id": 2, "name": "lesson 2", "segment_type": "video", "data": "www.hey.com/1" },
          { "id": 3, "name": "lesson 3", "segment_type": "video", "data": "www.hey.com/1" },
          { "id": 4, "name": "quiz 1", "segment_type": "quiz1", "questions": [
                                                                   {"id":1, "name":"q1"}] },
        ]
    }
}

let result = course.data.segments.find((c) => c.id === 4);

console.log(result)

您还需要确保在定义getCurrentSegment之前不要呼叫this.course。试试这个

ngOnInit() {
    // save this course id from course-detail component and get request from service
    this.courseId = JSON.parse(localStorage.getItem("courseId"))
    this.getCourse(this.courseId);

    this.courseService.getCourse(this.courseId).subscribe(
        course => {
            this.course = course;
            const id = +this.route.snapshot.paramMap.get('id');
            this.getCurrentSegment(this.course, id);
        },
        error  => this.errorMessage = <any>error
      );
  }