介绍
在Ng Alian脚手架里面,有一个很常用的组件,叫SF组件,也就是表单组件。
通过配置对象,赋值给SF的schema属性,可以快速地生成表单项,用于表单输入。
比如配置widget='date'生成日期组件,widget='select'生成单/多选组件。
但这些'date'、'select'都是SF组件预定义的。如果想要使用SF的同时,指定'abc',生成自己的自定义表单项组件,这时候就需要自定义了。
如何自定义
举个例子,需要一个组件,有两个文本框。输入,表示价格范围从多少到多少。而且可以通过SF生成。
1、首先,写组件.html,自定义组件要包在特殊标签里面
<sf-item-wrap [id]="id" [schema]="schema" [ui]="ui" [showError]="showError" [error]="error" [showTitle]="schema.title">
<!-- 开始自定义控件区域 -->
...
<!-- 结束自定义控件区域 -->
</sf-item-wrap>
2、写组件.ts,继承ControlWidget
import { ControlWidget } from '@delon/form'; // 导入
export class ProductWidgetRangeInputComponent extends ControlWidget {
}
2、定义指定哪个字符串(KEY),可以生成你自定义的组件
export class ProductWidgetRangeInputComponent extends ControlWidget {
static readonly KEY = 'range-input';
}
3、在适当的时候,调用setValue。(为的是把你自定义的组件的值,带出给SF组件,提交表单的时候用)
// 两个文本框的ngModel
// from;
// to;
// 两个文本框的ngModelChange方法里
ngModelChange() {
const v = { from: this.from, to: this.to };
this.setValue(v);
}
4、实现reset方法。(为的是把SF带入过来的值,给到你自定义的组件,更新自定义组件的UI。通过SF,设表单项默认值的时候用到)
reset(value: any) {
const { from, to } = value;
this.from = from;
this.to = to;
this.setValue(value);
}
5、到此,自定义小部件已经完成。外部是这样用的:
// .ts
sfSchema = {
properties: {
range: {
type: 'string',
title: '价格范围(元)',
default: { from: 0, to: 99 }, // 设默认值
ui: {
widget: 'range-input', // 自定义小部件的KEY
}
}
}
}
// .html
<sf [schema]="sfSchema"></sf>
6、另外,还需要注册一下这个自定义小部件,即可使用
// app.module.ts
import { WidgetRegistry } from '@delon/form'; // 导入SF相关库,在这里注册
import { ProductWidgetRangeInputComponent } from './widget/range-input.component'; // 自定义的小部件
export class AppModule {
constructor(widgetRegistry: WidgetRegistry) {
widgetRegistry.register(ProductWidgetRangeInputComponent.KEY /* 'range-input' */, ProductWidgetRangeInputComponent);
}
}
完整代码
range-input.component.html
<sf-item-wrap [id]="id" [schema]="schema" [ui]="ui" [showError]="showError" [error]="error" [showTitle]="schema.title">
<!-- 开始自定义控件区域 -->
<div nz-row>
<div nz-col nzSpan="10"><input type="text" placeholder="从" nz-input [(ngModel)]="from" (ngModelChange)="onChange()"></div>
<div nz-col nzSpan="4" nzPush="2">-</div>
<div nz-col nzSpan="10"><input type="text" placeholder="到" nz-input [(ngModel)]="to" (ngModelChange)="onChange()"></div>
</div>
<!-- 结束自定义控件区域 -->
</sf-item-wrap>
range-input.component.ts
import { ControlWidget } from '@delon/form';
@Component({
selector: 'app-product-widget-range-input',
templateUrl: './range-input.component.html',
})
export class ProductWidgetRangeInputComponent extends ControlWidget {
/* 用于注册小部件 KEY 值 */
static readonly KEY = 'range-input';
// 价格区间
from: any;
to: any;
getRange = () => {
return {
from: this.from,
to: this.to,
};
}
onChange() {
const v = this.getRange();
this.setValue(v);
}
// reset 可以更好的解决表单重置过程中所需要的新数据问题
reset(value: any) {
const { from, to } = value;
this.from = from;
this.to = to;
this.setValue(value);
}
}
网友评论