前面我们以`国家`为例,介绍了如何使用`数组型`数据字典。在这里,我们以`城市`为例,介绍如何使用`树型`数据字典 由于选择的`国家`不同,所使用的`城市`数据字典也就不同,也就存在`国家`和`城市`的数据联动。基于循序渐进的原则,我们先介绍如何使用`中国`的`城市`数据字典,在下一篇中再讲述如何实现`国家`和`城市`的数据联动 ## 0. 创建城市数据字典 如何创建数据字典,请参见:[创建数据字典](https://cabloy.com/zh-cn/articles/dict-create.html) 在这里,我们只需要看看树形数据字典的数据结构是什么模样: `src/module-system/a-dictbooster/backend/src/config/static/dict/cities/citiesChina.json` ``` javascript [ { "code": "110000", "title": "北京市", "children": [ { "code": "110100", "title": "北京市", "children": [ { "code": "110101", "title": "东城区" }, { "code": "110102", "title": "西城区" }], }], }], ``` | 名称 | 说明 | |----|----| | code | 字典项的唯一标识 | | title | 字典项的标题 | | children | 字典项的子项 | 与`数组型`数据字典相比,`树型`数据字典有以下两点不同: 1. `code`:在数据库中存储`完整路径`,比如:用户选择`东城区`,那么`code`值就是:`110000/110100/110101`。这样设计有两点好处: 1. 便于进行`code/title`转换,而且转换后的`title`也可以是完整路径,如:`北京市/北京市/东城区` 2. 便于按`不同层级`检索数据:可以直接构造模糊查询条件,比如,我们要查询整个北京市的数据,就可以这样:`select * from testParty where partyCity like ‘110000/110100/%‘` 2. `children`:通过`children`扩展数据字典的层级 ## 1. 前端表单渲染 `src/suite-vendor/test-party/modules/test-party/backend/src/config/validation/schema/party.js` ``` javascript schemas.party = { type: 'object', properties: { ... partyCity: { type: 'string', ebType: 'dict', ebTitle: 'Party City', ebParams: { dictKey: 'a-dictbooster:citiesChina', mode: 'tree', separator: '/', leafOnly: true, }, }, ... }, }; ``` | 名称 | 说明 | |----|----| | type | 字段类型 | | ebType | 字段渲染类型,用于标示前端渲染组件类型。`dict`是系统内置的字典组件 | | ebTitle | 字段标题,用于前端渲染,支持国际化 | | ebParams | 渲染参数,具体内容由渲染组件决定 | * ebParams | 名称 | 说明 | |----|----| | dictKey | 所使用数据字典的`atomStaticKey` | | mode | 数据字典的显示模式,`tree`是显示为`树型选择框`的模式 | | separator | 多级字典项的`title`在合并时所采用的分隔符 | | leafOnly | 当选择字典项时,是否只能选择`叶子结点` | ## 2. 后端code/title转换 同样,树型数据字典的`code/title`转换也是在后端进行。树型数据字典的`code`值在存入数据库时采用的是`完整路径`,在进行转换时也会生成完整路径的`title`。这一切也是CabloyJS的内置功能,我们只需要在`宴会`的`meta`信息中配置一下即可: `src/suite-vendor/test-party/modules/test-party/backend/src/meta.js` ``` javascript base: { atoms: { party: { info: { ... dict: { fields: { ... partyCity: { dictKey: 'a-dictbooster:citiesChina', separator: '/', }, ... }, }, }, }, }, }, ``` * dict.fields.partyCity | 名称 | 说明 | |----|----| | dictKey | 所使用数据字典的`atomStaticKey` | | separator | 多级字典项的`title`在合并时所采用的分隔符 | ## 3. 前端显示Title 后端方法`ctx.bean.atom.select`和`ctx.bean.atom.read`在查询到数据后,自动进行`code/title`转换,并把转换后的`title`写入数据,方便前端显示。写入数据的字段名规则如下: | code字段 | title字段 | title国际化字段 | |----|----|----| | name | \_{name}Title | \_{name}TitleLocale | | partyCity | \_partyCityTitle | \_partyCityTitleLocale | 比如,在`PC布局`中,通过`表格`形式显示宴会列表,表格中`城市`的字段配置如下: `src/suite-vendor/test-party/modules/test-party/front/src/config/config/configPartyRenderList.js` ``` javascript layouts: { table: { blocks: { items: { columns: [ { dataIndex: '_partyCityTitleLocale', title: 'Party City', align: 'left', }, ... ], }, }, }, }, ``` * layouts.table.blocks.items.columns | 名称 | 说明 | |----|----| | dataIndex | 要显示的字段名 | | title | 字段标题,支持国际化 | | align | 对齐方式 |