feat: add virtual attribute geter & setter support (#27)
This commit is contained in:
parent
befe5661f8
commit
b6cb185380
@ -17,6 +17,31 @@ describe('base model', () => {
|
||||
name: 'name',
|
||||
type: 'string',
|
||||
},
|
||||
{
|
||||
name: 'title',
|
||||
type: 'virtual',
|
||||
},
|
||||
{
|
||||
name: 'content',
|
||||
type: 'virtual',
|
||||
set(val) {
|
||||
// 留空
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'key1',
|
||||
type: 'virtual',
|
||||
set(val) {
|
||||
this.setDataValue('options.key1', `111${val}111`);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'key2',
|
||||
type: 'virtual',
|
||||
get() {
|
||||
return 'val2';
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'json',
|
||||
name: 'component',
|
||||
@ -143,4 +168,25 @@ describe('base model', () => {
|
||||
arr: [{a: 'a'}, {b: 'b'}],
|
||||
});
|
||||
});
|
||||
|
||||
it.only('update virtual attribute', async () => {
|
||||
await test.update({
|
||||
title: 'xxx', // 虚拟字段没 set 转存 options
|
||||
content: 'content123', // set 留空,这个 key 什么也不做
|
||||
key1: 'val1', // 走 set 方法
|
||||
});
|
||||
// 重新获取再验证
|
||||
const test2 = await TestModel.findByPk(test.id);
|
||||
expect(test2.get()).toMatchObject({
|
||||
abc: { aa: 'aa', bb: 'bb' },
|
||||
bcd: 'bbb',
|
||||
name: '123',
|
||||
component: { a: 'a', b: 'b' },
|
||||
arr: [{a: 'a'}, {b: 'b'}],
|
||||
title: 'xxx',
|
||||
key2: 'val2', // key2 为 get 方法取的
|
||||
key1: '111val1111',
|
||||
});
|
||||
expect(test2.get('content')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
@ -50,7 +50,7 @@ export default {
|
||||
{
|
||||
interface: 'string',
|
||||
type: 'virtual',
|
||||
name: 'options.icon',
|
||||
name: 'icon',
|
||||
title: '图标',
|
||||
component: {
|
||||
type: 'string',
|
||||
@ -62,7 +62,7 @@ export default {
|
||||
{
|
||||
interface: 'radio',
|
||||
type: 'virtual',
|
||||
name: 'options.defaultView',
|
||||
name: 'defaultView',
|
||||
title: '默认视图',
|
||||
defaultValue: 'table',
|
||||
dataSource: [
|
||||
@ -80,7 +80,7 @@ export default {
|
||||
{
|
||||
interface: 'radio',
|
||||
type: 'virtual',
|
||||
name: 'options.mode',
|
||||
name: 'mode',
|
||||
title: '表格模式',
|
||||
defaultValue: 'default',
|
||||
dataSource: [
|
||||
@ -99,7 +99,7 @@ export default {
|
||||
{
|
||||
interface: 'radio',
|
||||
type: 'virtual',
|
||||
name: 'options.defaultPerPage',
|
||||
name: 'defaultPerPage',
|
||||
title: '每页显示几行数据',
|
||||
defaultValue: 50,
|
||||
dataSource: [
|
||||
@ -116,7 +116,7 @@ export default {
|
||||
{
|
||||
interface: 'boolean',
|
||||
type: 'virtual',
|
||||
name: 'options.draggable',
|
||||
name: 'draggable',
|
||||
title: '支持拖拽数据排序',
|
||||
showInForm: true,
|
||||
showInDetail: true,
|
||||
|
@ -62,7 +62,7 @@ export default {
|
||||
{
|
||||
interface: 'subTable',
|
||||
type: 'virtual',
|
||||
name: 'options.dataSource',
|
||||
name: 'dataSource',
|
||||
title: '可选项',
|
||||
component: {
|
||||
type: 'table',
|
||||
|
@ -63,7 +63,7 @@ export default {
|
||||
{
|
||||
interface: 'string',
|
||||
type: 'virtual',
|
||||
name: 'options.association',
|
||||
name: 'association',
|
||||
title: '相关数据表',
|
||||
component: {
|
||||
type: 'string',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import { Model } from '@nocobase/database';
|
||||
import { getDataTypeKey, Model } from '@nocobase/database';
|
||||
|
||||
export class BaseModel extends Model {
|
||||
get additionalAttribute() {
|
||||
@ -7,11 +7,28 @@ export class BaseModel extends Model {
|
||||
return _.get(tableOptions, 'additionalAttribute') || 'options';
|
||||
}
|
||||
|
||||
hasGetAttribute(key: string) {
|
||||
const attribute = this.rawAttributes[key];
|
||||
// virtual 如果有 get 方法就直接走 get
|
||||
if (attribute && attribute.type && getDataTypeKey(attribute.type) === 'VIRTUAL') {
|
||||
return !!attribute.get;
|
||||
}
|
||||
return !!attribute;
|
||||
}
|
||||
|
||||
hasSetAttribute(key: string) {
|
||||
const attribute = this.rawAttributes[key];
|
||||
// virtual 如果有 set 方法就直接走 set
|
||||
if (attribute && attribute.type && getDataTypeKey(attribute.type) === 'VIRTUAL') {
|
||||
return !!attribute.set;
|
||||
}
|
||||
return !!attribute;
|
||||
}
|
||||
|
||||
get(key?: any, options?: any) {
|
||||
if (typeof key === 'string') {
|
||||
const [column, ...path] = key.split('.');
|
||||
const attribute = this.rawAttributes[column];
|
||||
if (attribute) {
|
||||
if (this.hasGetAttribute(column)) {
|
||||
const value = super.get(column, options);
|
||||
if (path.length) {
|
||||
return _.get(value, path);
|
||||
@ -29,8 +46,7 @@ export class BaseModel extends Model {
|
||||
|
||||
getDataValue(key: any) {
|
||||
const [column, ...path] = key.split('.');
|
||||
const attribute = this.rawAttributes[column];
|
||||
if (attribute) {
|
||||
if (this.hasGetAttribute(column)) {
|
||||
const value = super.getDataValue(column);
|
||||
if (path.length) {
|
||||
return _.get(value, path);
|
||||
@ -54,8 +70,7 @@ export class BaseModel extends Model {
|
||||
}
|
||||
const [column, ...path] = key.split('.');
|
||||
this.changed(column, true);
|
||||
const attribute = this.rawAttributes[column];
|
||||
if (attribute) {
|
||||
if (this.hasSetAttribute(column)) {
|
||||
if (!path.length) {
|
||||
return super.set(key, value, options);
|
||||
}
|
||||
@ -83,8 +98,7 @@ export class BaseModel extends Model {
|
||||
}
|
||||
const [column, ...path] = key.split('.');
|
||||
this.changed(column, true);
|
||||
const attribute = this.rawAttributes[column];
|
||||
if (attribute) {
|
||||
if (this.hasSetAttribute(column)) {
|
||||
if (!path.length) {
|
||||
return super.setDataValue(key, value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user