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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:03:23