使

使用指令在 Angular 中实现全屏切换功能。

2025-06-08

使用指令在 Angular 中实现全屏切换功能。

我们将看到如何利用指令的力量来创建一个超级简单的全屏切换功能。

让我们看看 Angular 中指令的定义:

指令是为 Angular 应用中元素添加额外行为的类。使用 Angular 的内置指令,你可以管理表单、列表、样式以及用户看到的内容。

正如定义所说,我们可以使用它为元素添加额外的行为。如果这还不够酷,我就不知道还有什么酷了。

这是我的一个项目中该指令的一个小演示(https://cartella.sreyaj.dev

全屏切换

Angular 中的指令

对于刚开始使用 Angular 的人来说,指令这个术语及其工作原理可能会令人困惑。大多数人只会使用一些最常见的指令,例如

  • NgClass
  • NgStyle
  • NgIf
  • NgFor

我们其实不必关心添加 this 后会如何神奇地实现这些功能。我们可能知道,要有条件地渲染一个元素,可以使用*ngIfand ,只有当条件成立时才渲染该元素。故事就到此为止!

我想给那些正在掌握 Angular 的人的一条建议是尝试深入研究这些功能并尝试找到底层实现。

Angular 提供了非常详尽的文档,讲解了不同类型的指令及其使用方法。阅读链接:
https://angular.io/guide/built-in-directives#built-in-directives

提示:要查看内置指令是如何编写的,只需访问其 API 文档页面并单击code图标即可转到 repo 中的直接文件:

Angular 文档

创建全屏指令

Angular 中的全屏指令

所以今天我们将构建一个自定义指令,它将帮助我们实现一项功能——最大化和最小化元素。

话不多说,让我们开始吧。

1. 为我们的指令创建一个模块

这实际上是可选的。但我确实喜欢创建一个模块,然后从这个模块声明并导出该指令。然后,只要我需要这个功能,我就会导入这个模块。

import { NgModule } from "@angular/core";
import { MaximizeDirective } from "./maxmimize.directive";

@NgModule({
  declarations: [MaximizeDirective],
  exports: [MaximizeDirective] //<-- Make sure to export it
})
export class MaximizeModule {}
Enter fullscreen mode Exit fullscreen mode

2.创建指令

接下来我们创建指令。我称之为maximize指令。创建指令后,我们来添加逻辑。

其基本思想是将元素(指令所在的位置)的宽度和高度设置为100vw100vh使其覆盖整个屏幕空间。在某些情况下,您可能还需要更改元素的位置。

import { Directive, ElementRef, Renderer2 } from "@angular/core";
import { BehaviorSubject } from "rxjs";
import { tap } from "rxjs/operators";
@Directive({
  selector: "[maximize]",
  exportAs: "maximize" // <-- Make not of this here
})
export class MaximizeDirective {
  private isMaximizedSubject = new BehaviorSubject(false);
  isMaximized$ = this.isMaximizedSubject.asObservable();
  constructor(private el: ElementRef, private renderer: Renderer2) {}

  toggle() {
    this.isMaximizedSubject?.getValue() ? this.minimize() : this.maximize();
  }
  maximize() {
    if (this.el) {
      this.isMaximizedSubject.next(true);
      this.renderer.addClass(this.el.nativeElement, "fullscreen");
    }
  }
  minimize() {
    if (this.el) {
      this.isMaximizedSubject.next(false);
      this.renderer.removeClass(this.el.nativeElement, "fullscreen");
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

让我为你们分解一下代码。

首先,我们需要获取应用该指令的元素。我们通过ElementRef在构造函数中注入来实现。这将提供对该元素的引用。

接下来,我们保留一个主题来维护指令的状态(以了解我们当前是最小化还是最大化)。

修改元素属性

因此我定义了一个 CSS 类,它只修改高度和宽度:

.fullscreen {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
}
Enter fullscreen mode Exit fullscreen mode

现在的想法是,当用户希望它处于全屏模式时,切换这个类。为此,我们掌握了Renderer2( Doc ),这是一种在 Angular 中操作 DOM 元素的好方法。

因此,编写两个函数,一个用于添加类,一个用于删除类。当调用这两个函数时,我们会更新状态。

添加了另一个函数,toggle以便用户无需了解当前状态即可执行操作。

导出指令实例

在上面的部分中,我标记了特定的一行代码:

@Directive({
  selector: "[maximize]",
  exportAs: "maximize" // <-- Make not of this here
})
Enter fullscreen mode Exit fullscreen mode

这是 Angular 提供的一个非常有趣的功能。在指令中,我们可以指定是否要在模板中启用该实例。

阅读此处:https://angular.io/api/core/Directive#exportas

它的作用是使用指定的名称在模板中提供指令实例:

<div class="card" maximize #maximize="maximize">
     <p>{{(maximize.isMaximized$ | async)}}</p>
 </div>
Enter fullscreen mode Exit fullscreen mode

isMaximized$看看我是如何在模板中访问指令的属性的。同样,指令的所有公共属性都可以使用 访问maximize

用法

要使用该指令,首先我在我的 中导入该模块AppModule。如果您已经在 中声明了该指令AppModule,则可以跳过此步骤。

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";
import { MaximizeModule } from "./maximize/maximize.module";
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, MaximizeModule], // <-- Imported the module
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}
Enter fullscreen mode Exit fullscreen mode

在您的模板中,您现在可以将指令添加到任何元素

 <div class="card" maximize #maximize="maximize">
      <button class="min-button"
          (click)="maximize.minimize()">
      </button>
      <button class="max-button"
          (click)="maximize.maximize()">
      </button>
 </div>
Enter fullscreen mode Exit fullscreen mode

因此,就像我们在讨论获取实例的部分中看到的那样,我们可以获取指令中的minimize()和函数来分别应用/删除类。maximize()

额外福利 - 浏览器也可全屏显示

所以我们所做的只是最大化元素,但您还想让浏览器全屏显示,我们也可以添加它。

  1. 安装screenfull
npm i screenfull
Enter fullscreen mode Exit fullscreen mode
  1. 像这样更新指令:
...
import * as Fullscreen from "screenfull"; // <-- add the import
...
maximize() {
    if (this.el) {
      this.isMaximizedSubject.next(true);
      this.renderer.addClass(this.el.nativeElement, "fullscreen");
      if (Fullscreen.isEnabled) { 
        Fullscreen.request(); // <-- request fullscreen mode
      }
    }
  }
  minimize() {
    if (this.el) {
      this.isMaximizedSubject.next(false);
      this.renderer.removeClass(this.el.nativeElement, "fullscreen");
      if (Fullscreen.isEnabled) {
        Fullscreen.exit(); // <-- exit fullscreen mode
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

注意:您可能需要在单独的窗口中打开沙盒预览以使全屏工作正常,或者直接访问此预览 URL:https://x6epr.csb.app/

代码

请在评论区留言,分享你的想法。
注意安全❤️

鏂囩珷鏉ユ簮锛�https://dev.to/angular/fullscreen-toggle-functionity-in-angular-using-directives-59n0
PREV
在 TypeScript 中管理键值常量
NEXT
Decorators do not work as you might expect 🤔 Quick Recap on Decorators The @Clamp Decorator Exploring decorators under the hood The Problem Creating instance-targeted decorators Bonus Conclusion Special Thanks