如何实现类似DevExtreme的Angular组件@Input输入参数分组配置
实现方案
核心原理是父组件通过@ContentChild/@ContentChildren获取嵌套的配置子组件实例,直接读取子组件的@Input属性作为分组配置,具体实现步骤如下:
1. 创建分组配置子组件
针对每个配置分组单独开发轻量化的子组件,仅定义该分组下的所有配置参数即可,不需要额外业务逻辑和渲染内容:
// dxo-paging.component.ts import { Component, Input } from '@angular/core'; @Component({ selector: 'dxo-paging', template: '' // 配置类组件不需要渲染UI,空模板即可 }) export class DxoPagingComponent { @Input() pageSize: number = 10; // 默认值可以直接在这里定义 @Input() pageIndex: number = 0; @Input() showPageSizeSelector: boolean = false; // 其他所有分页相关配置项都可以在这里扩展 }
2. 父组件中获取配置子组件实例
在根组件(如DxDataGridComponent)中通过内容查询获取嵌套的配置子组件,初始化完成后直接读取其属性作为配置:
// dx-data-grid.component.ts import { Component, Input, ContentChild, AfterContentInit } from '@angular/core'; import { DxoPagingComponent } from './dxo-paging.component'; @Component({ selector: 'dx-data-grid', template: `<!-- 组件主体渲染逻辑 -->` }) export class DxDataGridComponent implements AfterContentInit { // 原有全局根配置项 @Input() dataSource: any[] = []; @Input() remoteOperations: boolean = false; // 查询嵌套的分页配置子组件实例 @ContentChild(DxoPagingComponent) pagingConfig!: DxoPagingComponent; ngAfterContentInit(): void { // 内容初始化完成后即可拿到所有配置参数 // 若用户未传入对应配置子组件,可手动初始化默认配置 if (!this.pagingConfig) { this.pagingConfig = new DxoPagingComponent(); } // 后续业务逻辑直接读取this.pagingConfig下的属性即可 } }
3. 模块中注册组件
在对应功能模块的声明和导出列表中同时加入根组件和所有配置子组件,业务侧才能正常使用:
// data-grid.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { DxDataGridComponent } from './dx-data-grid.component'; import { DxoPagingComponent } from './dxo-paging.component'; @NgModule({ declarations: [DxDataGridComponent, DxoPagingComponent], imports: [CommonModule], exports: [DxDataGridComponent, DxoPagingComponent] }) export class DataGridModule {}
4. 业务侧使用效果
和DevExtreme官方用法完全一致:
<dx-data-grid [dataSource]="dataSource" [remoteOperations]="false"> <dxo-paging [pageSize]="10" [showPageSizeSelector]="true"></dxo-paging> </dx-data-grid>
扩展说明
- 如果是多实例同类型配置(如表格列定义),可以用
@ContentChildren获取配置组件的实例数组 - 要实现配置变更实时响应,可以给配置子组件的
@Input加setter,或者通过RxJS Subject抛出变更事件,父组件订阅后同步更新即可 - 不想写太多空模板组件的话,也可以用指令代替配置子组件,把selector改成属性选择器
[dxoPaging],用法改为<ng-template dxoPaging [pageSize]="10"></ng-template>,效果完全一致
内容的提问来源于stack exchange,提问作者user3471528
相关产品推荐
相关产品推荐

