You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular中配置课程课时播放器,实现点击课时加载对应视频

实现思路

你当前的两个组件属于同父级的兄弟组件,轻量场景下通过父组件做状态中转即可实现通信,整体链路为「课时组件抛出选中事件→父组件接收并存储当前选中课时→父组件将选中课时传递给播放器」,实现成本低且易维护。


第一步:改造课时列表组件(app-lesson-card)

给课时项增加点击事件,通过Output将选中的课时抛给父组件:

  1. 组件类新增Output事件和点击处理逻辑:
import { Component, Input, Output, EventEmitter } from '@angular/core';

export class LessonCardComponent {
  @Input() course: ICourse;
  // 对外抛出选中的课时
  @Output() lessonSelected = new EventEmitter<ILesson>();

  onLessonClick(lesson: ILesson) {
    // 已报名才允许切换课时,未报名可自行扩展提示逻辑
    if (this.course.enrolled) {
      this.lessonSelected.emit(lesson);
    }
  }

  // 保留你原有的enrollCourse等逻辑
}
  1. 模板中给课时行绑定点击事件:
<!-- 原有循环行新增点击事件和样式提示 -->
<div class='flex items-center justify-between top-margin' 
     *ngFor='let lessonData of course.lessons'
     (click)="onLessonClick(lessonData)"
     [ngClass]="{'cursor-pointer': course.enrolled, 'opacity-70': !course.enrolled}">
  <!-- 内部原有内容保持不变 -->
</div>

第二步:改造父组件做状态中转

  1. 父组件类新增当前选中课时的存储逻辑:
export class CourseDetailsComponent {
  course: ICourse; // 你原有定义的课程属性
  currentLesson: ILesson; // 存储当前选中的课时

  // 你原有获取课程数据的逻辑里,加默认播放第一个课时的赋值
  fetchCourseInfo() {
    // 原有接口请求逻辑
    this.course = 接口返回的课程数据;
    this.currentLesson = this.course.lessons[0];
  }

  // 接收课时组件抛出的选中事件
  onLessonSelected(lesson: ILesson) {
    this.currentLesson = lesson;
  }
}
  1. 父组件模板绑定事件和传值:
<div class='course-details'>
  <div>
     <!-- 给播放器新增传递当前选中课时 -->
     <app-course-player [course]='course' [currentLesson]="currentLesson"></app-course-player>
  </div>
 <div>
    <!-- 监听课时组件的选中事件 -->
    <app-lesson-card class='w-full' [course]='course' (lessonSelected)="onLessonSelected($event)"></app-lesson-card>
</div>
</div>

第三步:改造播放器组件适配切换逻辑

你原有代码用*ngFor循环了所有课时的播放器,会渲染多个播放器实例,需要调整为只渲染当前选中的课时:

  1. 播放器组件类新增Input属性:
import { Component, Input, ViewChild, ElementRef, SimpleChanges } from '@angular/core';

export class CoursePlayerComponent {
  @Input() course: ICourse;
  @Input() currentLesson: ILesson;
  @ViewChild('myMedia') myMedia: ElementRef<HTMLVideoElement>; // 用于操作播放器

  // 可选:切换课时后自动播放
  ngOnChanges(changes: SimpleChanges) {
    if (changes['currentLesson'] && this.myMedia) {
      this.myMedia.nativeElement.play();
    }
  }
}
  1. 播放器模板去掉循环,直接使用当前选中课时:
<!-- 去掉原来的*ngFor循环外层div -->
<vg-player class='w-full  video-size'>
    <vg-overlay-play vgFor='dreamclass-video'></vg-overlay-play>
    <vg-controls>
        <vg-play-pause></vg-play-pause>
        <vg-playback-button></vg-playback-button>
        <vg-scrub-bar>
            <vg-scrub-bar-current-time></vg-scrub-bar-current-time>
            <vg-scrub-bar-buffering-time></vg-scrub-bar-buffering-time>
        </vg-scrub-bar>
        <vg-time-display vgProperty='left' vgFormat='mm:ss'></vg-time-display>
        <vg-mute></vg-mute>
        <vg-fullscreen></vg-fullscreen>
    </vg-controls>
    <video #myMedia
           [vgMedia]='myMedia'
           [poster]='"img-proxy/plain/" + currentLesson.coverUrl'
           id='dreamclass-video'
           [src]='currentLesson.videoUrl'>
    </video>
</vg-player>

其他可选方案

如果你的项目层级较深、选中课时状态需要跨多组件复用,可以单独封装一个课程状态服务,通过BehaviorSubject存储当前选中课时,两个子组件都注入服务实现通信,适合复杂业务场景。

内容的提问来源于stack exchange,提问作者digitalboot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 05:54:03