自定义小部件

写在前面

@delon/form 尽可能满足不同需求,除现有内置的十几种基础组件小部件外,可以通过以下两种方式进一步扩展需求:

自定义小部件

细节请参考 自定义小部件

制作小部件

制作一套项目需求的小部件,可以更快速的开发工作。

编写小部件

常见小部件库

默认情况下 @delon/form 实现了一些常见需求,但需要额外类库支持的,称它为第三方组件小部件,这一部分小部件存在于widgets-third目录里;你可以直接复制使用。

这些组件包括:

名称描述文档源代码
markdownMarkdown 编辑器文档源代码
tinymceTinymce 富文本框文档源代码
ueditorUEditor 富文本框文档源代码

自己创建小部件

小部件就是一个组件,你只需要继承 ControlWidget 就相当于构建一个小部件,其结构如下:

  1. import { Component, OnInit } from '@angular/core';
  2. import { ControlWidget } from '@delon/form';
  3. @Component({
  4. selector: 'sf-tinymce',
  5. template: `
  6. <sf-item-wrap [id]="id" [schema]="schema" [ui]="ui" [showError]="showError" [error]="error" [showTitle]="schema.title">
  7. <!-- 开始自定义控件区域 -->
  8. <tinymce
  9. [ngModel]="value"
  10. (ngModelChange)="change($event)"
  11. [config]="config"
  12. [loading]="loading">
  13. </tinymce>
  14. <!-- 结束自定义控件区域 -->
  15. </sf-item-wrap>`
  16. })
  17. export class TinymceWidget extends ControlWidget implements OnInit {
  18. /* 用于注册小部件 KEY 值 */
  19. static readonly KEY = 'tinymce';
  20. // 组件所需要的参数,建议使用 `ngOnInit` 获取
  21. config: any;
  22. loadingTip: string;
  23. ngOnInit(): void {
  24. this.loadingTip = this.ui.loadingTip || '加载中……';
  25. this.config = this.ui.config || {};
  26. }
  27. // reset 可以更好的解决表单重置过程中所需要的新数据问题
  28. reset(value: string) {
  29. }
  30. change(value: string) {
  31. if (this.ui.change) this.ui.change(value);
  32. this.setValue(value);
  33. }
  34. }

sf-item-wrap

在模板中唯一是利用 sf-item-wrap 包裹自定义内容,它内部封装表单基础元素。

变更检测

小部件在渲染过程是手动变更检测,大部分情况下 ControlWidget 已经很好的管理什么时机应该执行变更检测,在自定义小部件过程中可能会遇到异步操作导致界面并未渲染,此时可以调用 detectChanges() 方法来触发一次小部件节点的变更检测。

注册小部件

在根模块中定义(declarations)注册小部件组件,同时在模块中导入 WidgetRegistry 并注册自定义小部件。

  1. @NgModule({
  2. declarations: [ TinymceWidget ],
  3. imports: [
  4. DelonFormModule.forRoot()
  5. ]
  6. })
  7. export class AppModule {
  8. constructor(widgetRegistry: WidgetRegistry) {
  9. widgetRegistry.register(TinymceWidget.KEY, TinymceWidget);
  10. }
  11. }

当然为了更友好的维护,建议在Shared目录下定义一个专属 Json schema 模块,有兴趣可参考 ng-alain实现

使用自定义小部件

同其他小部件一样,只需要指定 widget 值,例如:

  1. "intro": {
  2. "type": "string",
  3. "ui": {
  4. "widget": "tinymce",
  5. "loadingTip": "loading..."
  6. }
  7. }