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

Angular 10中如何通过另一组件的点击事件修改iframe的src属性

问题描述

我需要实现点击菜单栏时修改iframe的src属性,菜单栏为独立组件,其下拉菜单支持切换语言,我希望根据选中的语言动态调整iframe的src。
菜单HTML代码如下,其中绑定了名为updateSrc()的方法:

<nav>
<div class="select-box">
                      <div class="select-box__current" tabindex="1">
                        <div class="select-box__value" (click)="updateSrc(first_url)">
                          <input class="select-box__input" type="radio" id="0" value="1" name="Ben" checked="checked"/>
                          <p class="select-box__input-text">Es</p>
                        </div>
                        <div class="select-box__value" (click)="updateSrc(second_url)">
                          <input class="select-box__input" type="radio" id="1" value="2" name="Ben"/>
                          <p class="select-box__input-text">En</p>
                        </div>
                        <div class="select-box__value">
                          <input class="select-box__input" type="radio" id="2" value="3" name="Ben"/>
                          <p class="select-box__input-text">It</p>
                        </div>
                        <img class="select-box__icon" src="http://cdn.onlinewebfonts.com/svg/img_295694.svg" alt="Arrow Icon" aria-hidden="true"/>
                      </div>
                      <ul class="select-box__list">
                        <li>
                          <label class="select-box__option" for="0" aria-hidden="aria-hidden">Es</label>
                        </li>
                        <li>
                          <label class="select-box__option" for="1" aria-hidden="aria-hidden">En</label>
                        </li>
                        <li>
                          <a href="https://esourcecapital.it/">
                          <label class="select-box__option" aria-hidden="aria-hidden">It</label>
                          </a>
                        </li>
                      </ul>
                    </div> 
</nav>

header组件的TS代码:

import { Component, OnInit } from '@angular/core';
import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {

  menu:boolean = false;

  constructor(private translate: TranslateService,
              private sanitizer: DomSanitizer)
    {  }

  ngOnInit(): void {

  }

  first_url = "https://www.youtube.com/embed/4oP20QZxahk";
  second_url = "https://www.youtube.com/embed/Q_ZPBqVF0_8";
  current_url: SafeUrl;

  updateSrc(url) {
    this.current_url=this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}

需要修改的iframe位于另一个组件中,对应代码如下:

<div class="center">
  <iframe width="640" height="360" id="frame" frameborder="0" src="https://www.youtube.com/embed/4oP20QZxahk" [src]="current_url" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<!--                            <div class="pairs">
                                <button md-button (click)="updateSrc(first_url)" id="first" class="top-link">Video en español</button>
                                <button md-button (click)="updateSrc(second_url)" id="second" class="top-link">Video in english</button>
                            </div> -->
</div>

上述代码在同一组件中可正常运行,但菜单与iframe分属不同组件时无法生效,请问该如何解决?

解决方案

你遇到的是Angular跨组件数据同步的问题,两个独立组件无法直接访问对方的内部变量,可根据组件的层级关系选择以下两种方案:

方案一:父子组件层级,用@Output+@Input中转

如果两个组件有共同的父组件,可通过父组件做数据中转:

  1. 修改header组件,对外抛出url变更事件
// header组件TS新增导入
import { Output, EventEmitter } from '@angular/core';
// 类内部新增输出事件
@Output() urlChange = new EventEmitter<string>();
// 修改updateSrc方法
updateSrc(url: string) {
  this.urlChange.emit(url);
}
  1. 父组件监听header的url变更事件,存储为公共变量
// 父组件TS
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
export class ParentComponent {
  currentIframeUrl: SafeUrl;
  constructor(private sanitizer: DomSanitizer) {}
  handleUrlChange(url: string) {
    this.currentIframeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}
<!-- 父组件模板 -->
<app-header (urlChange)="handleUrlChange($event)"></app-header>
<!-- 把url传给iframe所在的子组件 -->
<app-video-page [iframeUrl]="currentIframeUrl"></app-video-page>
  1. iframe所在组件新增输入属性接收url
// iframe组件TS
import { Input } from '@angular/core';
import { SafeUrl } from '@angular/platform-browser';
export class VideoPageComponent {
  @Input() iframeUrl: SafeUrl;
}
<!-- iframe组件模板修改src绑定 -->
<iframe width="640" height="360" id="frame" frameborder="0" [src]="iframeUrl" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

方案二:无直接层级关系,用公共服务共享状态

如果两个组件层级嵌套深、或者是平级无关组件,可通过全局共享服务实现状态同步:

  1. 新建全局共享服务video.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';

@Injectable({ providedIn: 'root' })
export class VideoService {
  // 初始默认url为西语视频
  private videoUrlSub = new BehaviorSubject<string>('https://www.youtube.com/embed/4oP20QZxahk');
  videoUrl$ = this.videoUrlSub.asObservable();

  constructor(private sanitizer: DomSanitizer) {}

  updateUrl(url: string) {
    this.videoUrlSub.next(url);
  }

  getSafeUrl(url: string): SafeUrl {
    return this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }
}
  1. header组件注入服务,点击时更新服务内的url
// header组件TS
constructor(
  private translate: TranslateService,
  private sanitizer: DomSanitizer,
  private videoService: VideoService
) {}

updateSrc(url: string) {
  this.videoService.updateUrl(url);
}
  1. iframe所在组件注入服务,订阅url变更
// iframe组件TS
import { Subscription } from 'rxjs';
export class VideoPageComponent implements OnInit, OnDestroy {
  currentUrl: SafeUrl;
  private sub: Subscription;
  constructor(private videoService: VideoService) {}

  ngOnInit() {
    this.sub = this.videoService.videoUrl$.subscribe(url => {
      this.currentUrl = this.videoService.getSafeUrl(url);
    });
  }

  ngOnDestroy() {
    // 销毁时取消订阅避免内存泄漏
    this.sub?.unsubscribe();
  }
}
<!-- iframe组件模板直接绑定currentUrl -->
<iframe width="640" height="360" id="frame" frameborder="0" [src]="currentUrl" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

内容的提问来源于stack exchange,提问作者Luis Alejandro López de Anda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:36:04