项目

模态框

ModalComponent@abp/ng.theme.shared 包暴露的一个预构建组件,用于显示模态框。该组件内部使用 ng-bootstrap 的模态框服务来渲染模态框。

abp-modal 提供了一些额外的好处:

  • 灵活。您可以通过将模板添加到 abp-modal 内容中,轻松传递头部、主体和页脚模板。它也可以快速实现。
  • 提供了多个输入属性以自定义模态框,以及多个输出事件以监听某些事件。
  • 自动检测附有 abpClose 指令的关闭按钮,并在按下此按钮时关闭模态框。
  • 自动检测 abp-button 并在模态框组件的 busy 输入值为 true 时触发其加载旋转器。
  • 自动检查模态框内的表单是否已更改但未保存。在这种情况下,当用户尝试关闭模态框或刷新/关闭浏览器标签页时,它会通过显示确认弹窗来警告用户。

注意:也可以使用 ng-bootstrap 模态框来渲染模态框。更多信息,请参阅 ng-bootstrap 文档中的模态框文档

入门指南

为了在 HTML 模板中使用 abp-modal,应将 ModalComponent 导入到您的组件中,如下所示:

// sample.component.ts
// ...
import { ModalComponent, ModalCloseDirective } from '@abp/ng.theme.shared';

@Component({
  //...
  ,
  imports: [
    // ..., 
    ModalComponent,
    ModalCloseDirective // 如果在 html 模板中使用 `abpClose` 指令
  ],
})
export class SampleComponent {
  isModalOpen = false;
}
<!-- sample.component.html -->

<button class="btn btn-primary" (click)="isModalOpen = true">
  打开模态框
</button>

<abp-modal [(visible)]="isModalOpen">
  <ng-template #abpHeader>
    <h3>模态框标题</h3>
  </ng-template>

  <ng-template #abpBody>
    <p>模态框内容</p>
  </ng-template>

  <ng-template #abpFooter>
    <button type="button" class="btn btn-secondary" abpClose>
      关闭
    </button>
  </ng-template>
</abp-modal>

示例模态框结果

查看模态框内表单的示例:

<!-- book.component.ts -->

<abp-modal [(visible)]="isModalOpen" [busy]="inProgress">
  <ng-template #abpHeader>
    <h3>书籍</h3>
  </ng-template>

  <ng-template #abpBody>
    <form id="book-form" [formGroup]="form" (ngSubmit)="save()">
      <div class="form-group">
        <label for="book-name">作者</label><span> * </span>
        <input type="text" id="author" class="form-control" formControlName="author" autofocus />
      </div>

      <div class="form-group">
        <label for="book-name">名称</label><span> * </span>
        <input type="text" id="book-name" class="form-control" formControlName="name" />
      </div>

      <div class="form-group">
        <label for="book-price">价格</label><span> * </span>
        <input type="number" id="book-price" class="form-control" formControlName="price" />
      </div>

      <div class="form-group">
        <label for="book-type">类型</label><span> * </span>
        <select class="form-control" id="book-type" formControlName="type">
          <option [ngValue]="null">选择书籍类型</option>
          <option [ngValue]="0">未定义</option>
          <option [ngValue]="1">冒险</option>
          <option [ngValue]="2">传记</option>
          <option [ngValue]="3">奇幻</option>
          <option [ngValue]="4">科学</option>
        </select>
      </div>

      <div class="form-group">
        <label for="book-publish-date">出版日期</label><span> * </span>
        <input
          id="book-publish-date"
          formControlName="publishDate"
          class="form-control"
          type="date"
        />
      </div>
    </form>
  </ng-template>

  <ng-template #abpFooter>
    <button type="button" class="btn btn-secondary" abpClose>
      取消
    </button>

    <button form="book-form" class="btn btn-primary" [disabled]="form.invalid || form.pristine">
      <i class="fa fa-check mr-1"></i>
      保存
    </button>
  </ng-template>
</abp-modal>
// book.component.ts

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { inject } from '@angular/core';

@Component(/* 组件元数据 */)
export class BookComponent {
  private fb = inject(FormBuilder);
  private service = inject(BookService);
  form = this.fb.group({
    author: [null, [Validators.required]],
    name: [null, [Validators.required]],
    price: [null, [Validators.required, Validators.min(0)]],
    type: [null, [Validators.required]],
    publishDate: [null, [Validators.required]],
  });

  inProgress: boolean;
  isModalOpen: boolean;

  save() {
    if (this.form.invalid) {
      return;
    }

    this.inProgress = true;

    this.service.save(this.form.value).subscribe(() => {
      this.inProgress = false;
    });
  }
}

带有表单的模态框如下所示:

表单示例结果

API

输入属性

visible

@Input() visible: boolean

visible 是一个布尔输入属性,用于控制模态框是否打开。

重要细节:

  • 默认值:false(模态框初始关闭)。
  • 必需绑定:您必须将 visible 绑定到组件属性。如果完全省略它,模态框将永远不会出现,因为只有在 visible 变为 true 时才会实例化。
  • 建议使用双向绑定:当组件需要关闭时(例如,用户按下关闭按钮或背景),组件会发出 visibleChange 事件。因此,不支持使用常量如 [visible]="true"visible="true" —— Angular 无法更新字面量,因此模态框无法正确关闭,并可能导致错误。始终绑定到变量。
  • 正确模式:
    • 首选简写:[(visible)]="isModalOpen"
    • 或显式形式:[visible]="isModalOpen" (visibleChange)="isModalOpen = $event"

示例(如上所示):

<abp-modal [(visible)]="isModalOpen">
  <!-- 内容 -->
</abp-modal>

程序化控制:

// 在组件类中
isModalOpen = false;

open() { this.isModalOpen = true; }
close() { this.isModalOpen = false; }

避免(错误):

<!-- 这将打开一次,但无法正确关闭,并可能抛出错误 -->
<abp-modal [visible]="true"></abp-modal>

busy

@Input() busy: boolean

busy 是一个布尔输入属性,用于确定模态框的繁忙状态是否为 true。当 busy 为 true 时,模态框无法关闭,并且 abp-button 的加载旋转器将被触发。

options

@Input() options: NgbModalOptions

options 是一个类型为 NgbModalOptions 的输入属性。它是 ng-bootstrap 模态框的配置。

示例:

  • animation:这是一个类型为 boolean 的 NgbModalOption 属性。它控制模态框打开和关闭时是否带有动画。默认情况下,它设置为 true,意味着模态框在打开和关闭时将具有平滑过渡。将其设置为 false 将禁用这些动画。
import { Component } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-options',
  ...})

export class NgbdModalOptions {
  modalService = inject(NgbModal);
  animationModal(content) {
    this.modalService.open(content, { animation: true });
  }
}

       此配置的结果如下:

模态框示例结果

       相反,如果我们将其设置为 false:

模态框示例结果

  • fullscreen:这是一个类型为 boolean 或 string 的 NgbModalOption 属性。当设置为 true 时,元素将展开以覆盖整个屏幕,隐藏所有其他界面元素。当设置为 false 时,元素保持其常规大小并在页面内保持其位置。
import { Component } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
 selector: 'ngbd-modal-options',
 ...})

export class NgbdModalOptions {
 modalService = inject(NgbModal);
 fullscreenModal(content) {
   this.modalService.open(content, { fullscreen: true });
 }
}

       如果 fullscreen: true

模态框示例结果

suppressUnsavedChangesWarning

@Input() suppressUnsavedChangesWarning: boolean

suppressUnsavedChangesWarning 是一个布尔输入属性,用于确定是否触发确认弹窗。它也可以全局设置,如下所示:

// app.config.ts

import { SUPPRESS_UNSAVED_CHANGES_WARNING } from '@abp/ng.theme.shared';

export const appConfig: ApplicationConfig = {
  providers: [
    // ...
    { provide: SUPPRESS_UNSAVED_CHANGES_WARNING, useValue: true }
  ],
};

注意:abp-modalsuppressUnsavedChangesWarning 输入值会覆盖 SUPPRESS_UNSAVED_CHANGES_WARNING 注入令牌的值。

输出事件

visibleChange

@Output() readonly visibleChange = new EventEmitter<boolean>();

visibleChange 是当模态框可见性更改时发出的事件。事件负载是一个布尔值。

appear

  @Output() readonly appear = new EventEmitter<void>();

appear 是当模态框已打开时发出的事件。

disappear

  @Output() readonly disappear = new EventEmitter<void>();

disappear 是当模态框已关闭时发出的事件。

在本文档中