Angular 2同级组件通信问题:点击视频项无法在详情组件显示详情
看起来你已经选对了用共享服务传递组件数据的方向,但还差几个关键环节没打通——点击视频时没把数据主动发送到共享服务里,服务本身也缺少传递数据的核心逻辑。我帮你一步步把这些缺口补上:
第一步:完善共享服务
AppService 首先得给服务加一个能传递数据的「管道」,用BehaviorSubject是最优选择(它能保存最新数据,就算详情页是后来才加载的,也能拿到之前点击的视频信息)。修改你的AppService代码:
import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AppService { // 创建一个BehaviorSubject,初始值设为null即可 private videoDetailsSubject = new BehaviorSubject<any>(null); // 对外暴露一个可观察对象,供组件订阅 videoDetails$: Observable<any> = this.videoDetailsSubject.asObservable(); constructor() { } // 定义方法,用来接收并发送视频详情数据 sendVideoDetails(details: any) { this.videoDetailsSubject.next(details); } // 保留你原本的getData方法 getData() { // 你的原有数据请求逻辑 } }
第二步:修改
VideoItemComponent,点击时主动发送数据 你现在的clickMe方法只是自己存了变量,完全没通知共享服务。现在调整这个组件,注入服务并发送数据:
import { Component, OnInit, Input} from '@angular/core'; import { AppService } from '../app.service'; // 引入共享服务 @Component({ selector: 'app-video-item', templateUrl: './video-item.component.html', styleUrls: ['./video-item.component.scss'] }) export class VideoItemComponent implements OnInit { @Input() item: any; // 注入共享服务 constructor(private appService: AppService) { } ngOnInit() { } clickMe(event){ // 把需要的视频字段打包成对象,也可以直接传整个item const videoDetails = { title: this.item.snippet.title, description: this.item.snippet.description, publishedAt: this.item.snippet.publishedAt, videoId: this.item.id // 根据你的实际数据结构调整,确保能拿到视频ID }; console.log('发送视频详情:', videoDetails); // 调用服务方法,把数据发出去 this.appService.sendVideoDetails(videoDetails); } }
第三步:修改
DetailsComponent,接收并展示数据 现在调整详情组件的订阅逻辑,接收完整的视频详情数据:
import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { AppService } from '../app.service'; import { Subscription } from 'rxjs'; @Component({ selector: 'app-details', templateUrl: './details.component.html', styleUrls: ['./details.component.scss'] }) export class DetailsComponent implements OnInit { id : string; private player; private ytEvent; myData; videoDetails: any; // 用来存储接收的视频详情 subscription: Subscription; constructor(private appService : AppService, private route : ActivatedRoute) { this.id = route.snapshot.params['videoId']; // 订阅服务的视频详情流 this.subscription = appService.videoDetails$.subscribe( details => { this.videoDetails = details; console.log('详情页收到数据:', details); }); } ngOnInit() { this.appService.getData().subscribe(data=> { console.log(data); this.myData = data; }) } // 保留你原本的播放器相关方法 onStateChange(event) { this.ytEvent = event.data; } savePlayer(player) { this.player = player; } playVideo() { this.player.playVideo(); } pauseVideo() { this.player.pauseVideo(); } }
最后:在详情页模板里展示数据
比如你的details.component.html可以这样写(用*ngIf确保有数据时再渲染):
<div *ngIf="videoDetails"> <h2>{{ videoDetails.title }}</h2> <p>发布时间: {{ videoDetails.publishedAt | date:'yyyy-MM-dd HH:mm' }}</p> <div class="description">{{ videoDetails.description }}</div> <!-- 你的视频播放器代码放在这里 --> </div>
为什么之前没生效?
你之前的VideoItemComponent只是自己存了变量,完全没把数据传递到共享服务里,服务的videoTitle$根本没收到任何值,所以详情页就算订阅了也拿不到数据。现在通过BehaviorSubject作为中间桥梁,点击时主动发送数据,详情页订阅接收,就能正常展示点击的视频详情了。
内容的提问来源于stack exchange,提问作者Sonal
相关产品推荐
相关产品推荐

