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
相关产品推荐
相关产品推荐

