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

Angular自定义全屏指令isFullScreen变量无法被组件模板访问

问题根因

你的代码存在4个核心错误,导致全屏状态无法同步到模板、点击按钮无响应:

  • 数据流方向错误:@Input() 仅支持组件到指令的单向值传递,指令内部修改isFullScreen不会同步回组件作用域。模板中访问的isFullScreen是组件自身的属性,和指令实例内部的属性是完全独立的两个变量,值无法联动。
  • 绑定语法错误:模板中写的[appFullScreen]="isFullScreen"是无效绑定,指令的输入属性名是isFullScreen,和选择器appFullScreen无关。
  • 缺少触发逻辑:指令内定义的openFullscreen()/closeFullscreen()方法没有绑定按钮点击事件,点击按钮不会执行全屏切换操作。
  • 全局对象引用不规范:代码中多处直接使用全局document对象,没有使用构造函数注入的this.document,存在跨环境(如服务端渲染)运行报错风险。

修复方案

1. 修正指令代码

新增双向绑定对应的事件发射器、绑定按钮点击事件、修正全局对象引用:

import { DOCUMENT } from '@angular/common';
import { Directive, HostListener, Inject, Input, Output, EventEmitter } from '@angular/core';

@Directive({
  selector: '[appFullScreen]'
})
export class FullScreenDirective {
  // 双向绑定输入属性
  @Input() isFullScreen: boolean = false;
  // Angular双向绑定规则:同名输入+Change后缀的发射器,自动同步状态
  @Output() isFullScreenChange = new EventEmitter<boolean>();
  elem: any;

  constructor(@Inject(DOCUMENT) private document: Document) { }

  ngOnInit(): void {
    this.chkScreenMode();
    // 统一使用注入的document对象,避免全局引用错误
    this.elem = this.document.documentElement;
  }

  // 监听各浏览器的全屏状态变更事件
  @HostListener('document:fullscreenchange')
  @HostListener('document:webkitfullscreenchange')
  @HostListener('document:mozfullscreenchange')
  @HostListener('document:MSFullscreenChange')
  onFullScreenChange() {
    this.chkScreenMode();
  }

  // 监听宿主按钮点击,自动切换全屏状态
  @HostListener('click')
  toggleFullScreen() {
    this.isFullScreen ? this.closeFullscreen() : this.openFullscreen();
  }

  chkScreenMode() {
    const currentState = !!this.document.fullscreenElement;
    if (currentState !== this.isFullScreen) {
      this.isFullScreen = currentState;
      // 将最新状态发射给组件,同步更新视图
      this.isFullScreenChange.emit(this.isFullScreen);
    }
  }
  
  openFullscreen() {
    if (this.elem.requestFullscreen) {
      this.elem.requestFullscreen();
    } else if (this.elem.mozRequestFullScreen) {
      /* Firefox */
      this.elem.mozRequestFullScreen();
    } else if (this.elem.webkitRequestFullscreen) {
      /* Chrome, Safari and Opera */
      this.elem.webkitRequestFullscreen();
    } else if (this.elem.msRequestFullscreen) {
      /* IE/Edge */
      this.elem.msRequestFullscreen();
    }
  }

  closeFullscreen() {
    if (this.document.exitFullscreen) {
      this.document.exitFullscreen();
    } else if (this.document.mozCancelFullScreen) {
      /* Firefox */
      this.document.mozCancelFullScreen();
    } else if (this.document.webkitExitFullscreen) {
      /* Chrome, Safari and Opera */
      this.document.webkitExitFullscreen();
    } else if (this.document.msExitFullscreen) {
      /* IE/Edge */
      this.document.msExitFullscreen();
    }
  }
}

2. 组件类配置

仅需要在组件类中声明状态属性即可,不需要额外编写全屏控制逻辑:

isFullScreen = false;

3. 修正模板绑定

使用Angular双向绑定语法连接指令和组件状态,移除无效的指令传值写法:

<button
  appFullScreen
  [(isFullScreen)]="isFullScreen"
  class="mat-icon-button"
  [ngClass]="{
    'exit-full-screen': isFullScreen,
    'enter-full-screen': !isFullScreen
  }"
  [matTooltip]="isFullScreen ? 'Exit fullScreen' : 'Enter fullScreen'"
>
  <mat-icon class="screen" *ngIf="!isFullScreen">fullscreen</mat-icon>
  <mat-icon class="screen" *ngIf="isFullScreen">fullscreen_exit</mat-icon>
</button>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:06:26