Angular 6父/子路由和共享数据

时间:2018-08-06 14:19:39

标签: html angular routing nested children

我在嵌套子代-父母路由和共享数据方面遇到问题。 我的项目包含4个组件:“课程列表”,“课程详细信息”,“课程播放”,“课程测验”,方案类似于(Click Here)。 数据是这样传递的:每个课程都有部分数组,每个部分都有问题数组。我从后端获得的所有数据都正确传递了。

我对课程测验和课程玩法与课程测验之间的路由有疑问。这就是我想要的:

  1. 单击链接开始课程播放测验后,该课程测验将在指定的div中打开,并从此开始生活。而且路线也会改变
  2. 我希望每次只显示一个问题,并通过下一个链接转到下一个问题

我确实使div更改为孩子的状态,但是路线没有改变,父母的数据也没有通过,我也不知道如何以我写的方式通过在2。

我没有添加课程列表,课程详细信息和课程服务,因为一切都很好,并且与该问题无关。这是所有相关的代码:

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

应用路由

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { CourseListComponent } from './courses/course-list/course-list.component';
import { CourseDetailComponent } from './courses/course-detail/course-detail.component';
import { CoursePlayComponent } from './courses/course-play/course-play.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { CourseQuizComponent } from './courses/course-play/course-quiz/course-quiz.component';


// Routing array - set routes to each html page
const appRoutes: Routes = [
  { path: '', redirectTo: '/courses', pathMatch: 'full', runGuardsAndResolvers: 'always' },
  { path: 'courses', component: CourseListComponent,  pathMatch: 'full', runGuardsAndResolvers: 'always' },
  { path: 'courses/:id', component: CourseDetailComponent, pathMatch: 'full', runGuardsAndResolvers: 'always' },
  { path: 'courses/:id/segments/:id', component: CoursePlayComponent, pathMatch: 'full', runGuardsAndResolvers: 'always',
    children: [{ path: 'questions/:id', component: CourseQuizComponent }]
  },
  { path: '**', component: PageNotFoundComponent, pathMatch: 'full', runGuardsAndResolvers: 'always' }];

@NgModule({
  imports: [RouterModule.forRoot(appRoutes, { onSameUrlNavigation: 'reload' })],
  exports: [RouterModule]
})

export class AppRoutingModule {  }

course-play.component

import { Component, OnInit } 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 { DomSanitizer } from '@angular/platform-browser';

import { ICourse } from '../course';
import { ISegment } 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;
  public showChildren: boolean;

  constructor(private courseService: CourseService,
      private route: ActivatedRoute,
      private router: Router,
      public sanitizer: DomSanitizer) { this.showChildren = false; }


    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 course detail by id
      getCourse(id: number) {
        this.courseService.getCourse(this.courseId).subscribe(
          course => {
              this.course = course;

              // get the current segment id to use it on the html file
              const id = +this.route.snapshot.paramMap.get('id');
              this.getCurrentSegment(id);
          },
          error  => this.errorMessage = <any>error);
        }

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

      changeShowChildren() {
        this.showChildren = !this.showChildren;
      }
}

course-play.html

  <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>
            <li class="course_play_item"  *ngFor="let lesson of unit.value">
              <a class="nav-link" [routerLink]="['/courses', course.id, 'segments', lesson.id]" (click)=getCurrentSegment(lesson.id)>{{lesson.name}} </a>
            </li>
          </ul>
        </div>
      </div>
    </div>

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

      <!-- Quiz Div -->
      <div class="col-md-12 course_play_body text-center" *ngIf="currentSegment.segment_type === 'Quiz'">
        <div class="col-md-12 course_play_body text-center" *ngIf="showChildren === false">
          <h1>{{currentSegment.name}}</h1>
          <p class="text-left"> Now that you've finished this unit, It's time to take a short quiz and see what you learned so far!
              You'll need to choose one out of four answers which you think is correct.
              After you've finished the quiz, you'll get your grade. feel free to re-take this quiz as much as you like.
              Good Luck!
            </p>
            <p class="big-text" *ngIf="currentSegment.questions?.lenght > 0"> {{currentSegment.questions?.lenght}} questions </p>
            <a (click) = "showChildren = true"><h4>Start Quiz</h4></a>
          </div>
            <quiz-course *ngIf="showChildren === true" [questions]="currentSegment?.questions"></quiz-course>
        </div>

  </div>

course-quiz.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 { ISegment } from '../../course';
import { IQuestion } from '../../course';
import { CourseService } from '../../course.service';

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

export class CourseQuizComponent implements OnInit {

  @Input() questions: IQuestion[];

  constructor(private courseService: CourseService,
      private route: ActivatedRoute,
      private router: Router) {}

  ngOnInit() {
  }

}

course-quiz.html

<ul *ngFor="let item of questions">
  <li>{{questions.question}}</li>
  <li>{{questions.answer1}</li>
  <li>{{questions.answer2}}</li>
  <li>{{questions.answer3}}</li>
  <li>{{questions.answer4}}</li>
</ul>

<a>Next Question</a>

0 个答案:

没有答案