自定义视图获取数据
在某些情况下,oinone 提供的默认视图无法满足需求,这时我们就需要自定义视图。通常,虽然视图的 UI 不足以满足要求,但数据结构是不变的。此时,重点是修改页面 UI,数据的请求与回填可以利用平台默认的能力。
如何实现?
- 界面设计器的使用
- 你可以通过界面设计器先配置页面,平台在运行时会根据设计器生成对应的 GraphQL 请求,并自动回填数据。
- 视图的数据结构
- 视图的数据类型分为可以分为 Object 跟 List
- Object 代表当前视图的数据结构是对象
- List 代表当前视图的数据结构是数组。
- 视图的数据类型分为可以分为 Object 跟 List
如果我们将 Object 跟 List 分的更细一点就变成了这样:
1: Object: 对象,代表当前视图的数据结构是单个对象,例如:表单视图、详情视图
1: List: 对象数组,代表当前视图的数据结构数组,例如:表格视图、卡片视图、画廊视图
视图类型 | 平台组件 | 数据属性 |
---|---|---|
表格视图 | TableWidget | dataSource |
画廊视图 | GalleryWidget | dataSource |
表单视图 | FormWidget | formData |
详情视图 | DetailWidget | formData |
自定义视图时,需要先确认当前视图的类型,再通过界面设计器进行页面配置。前端部分只需继承相应的组件,平台底层会自动处理接口数据的获取与回填。
表单视图示例:
import Form from './Form.vue';
// 自定义表单视图
@SPI.ClassFactory(
BaseElementWidget.Token({
widget: 'custom-form'
})
)
export class CustomForm extends FormWidget {
public initialize(props: Props) {
super.initialize(props);
this.setComponent(Form);
return this;
}
}
Vue 组件:
<template></template>
<script lang="ts">
export default defineComponent({
props: {
formData: {
// 当前表单的数据
type: Object,
default: () => ({})
}
}
});
</script>
自定义layout
// 原始的layout模版
<view type="FORM">
<element widget="actionBar" slot="actionBar" slotSupport="action">
<xslot name="actions" slotSupport="action" />
</element>
<element widget="form" slot="form">
<xslot name="fields" slotSupport="pack,field" />
</element>
</view>
//自定义的layout模版
<view type="FORM">
<element widget="actionBar" slot="actionBar" slotSupport="action">
<xslot name="actions" slotSupport="action" />
</element>
<element widget="custom-form" slot="form">
<xslot name="fields" slotSupport="pack,field" />
</element>
</view>
其实就是把 widget="form" 改成 widget="custom-form"
表格视图示例:
import Table from './Table.vue';
// 自定义表格视图
@SPI.ClassFactory(
BaseElementWidget.Token({
widget: 'custom-table'
})
)
export class CustomTable extends TableWidget {
public initialize(props: Props) {
super.initialize(props);
this.setComponent(Table);
return this;
}
}
Vue 组件:
<template></template>
<script lang="ts">
export default defineComponent({
props: {
dataSource: {
// 当前列表的数据
type: Object,
default: () => ({})
}
}
});
</script>
自定义layout
// 原始的layout模版
<view type="TABLE">
<pack widget="group">
<view type="SEARCH">
<element widget="search" slot="search" slotSupport="field">
<xslot name="searchFields" slotSupport="field" />
</element>
</view>
</pack>
<pack widget="group" slot="tableGroup">
<element widget="actionBar" slot="actionBar" slotSupport="action">
<xslot name="actions" slotSupport="action" />
</element>
<element widget="table" slot="table" slotSupport="field">
<element widget="expandColumn" slot="expandRow" />
<xslot name="fields" slotSupport="field" />
<element widget="rowActions" slot="rowActions" slotSupport="action" />
</element>
</pack>
</view>
//自定义的layout模版
<view type="TABLE">
<pack widget="group">
<view type="SEARCH">
<element widget="search" slot="search" slotSupport="field">
<xslot name="searchFields" slotSupport="field" />
</element>
</view>
</pack>
<pack widget="group" slot="tableGroup">
<element widget="actionBar" slot="actionBar" slotSupport="action">
<xslot name="actions" slotSupport="action" />
</element>
<element widget="custom-table" slot="table" slotSupport="field">
<element widget="expandColumn" slot="expandRow" />
<xslot name="fields" slotSupport="field" />
<element widget="rowActions" slot="rowActions" slotSupport="action" />
</element>
</pack>
</view>
其实就是把 widget="table" 改成 widget="custom-table"
以上代码展示了如何继承对应的 widget,平台会自动调用接口获取数据。如果你需要自定义接口调用,请参考然后参考这篇文章,调用接口。
自定义字段获取数据、提交数据
在 oinone 中,常见的自定义字段分为两种,一种是表单字段,一种是列表字段。
表单字段
1. 所有的表单字段都有 value 属性,用来存储当前字段对应的值
2. 所有的表单字段都有 formData 属性,用来获取其他字段的值,也可以修改其他字段的值
3. 所有的表单字段都有 change 方法,用来修改当前字段对应的值
示例:
@SPI.ClassFactory(
FormFieldWidget.Token({
viewType: [ViewType.Form, ViewType.Search],
ttype: ModelFieldType.String
})
)
export class CustomFormFieldWidget extends FormFieldWidget {
mounted() {
console.log(this.value); // 获取当前字段的值
console.log(this.formData); // 获取当前表单的值
this.change('hello'); // 修改当前字段的值
}
}
Vue 组件:
<template>
<div @click="change('hi')">{{ value }}</div>
</template>
<script lang="ts">
export default defineComponent({
props: {
value: {
type: String
},
change: {
type: Function
}
}
});
</script>
列表字段
- 所有的列表字段都有
dataSource
属性,用来获取当前列表的数据 - 所有的列表字段中的
renderDefaultSlot
方法,用来渲染单元格组件
示例:
@SPI.ClassFactory(
BaseFieldWidget.Token({
viewType: ViewType.Table,
ttype: [ModelFieldType.String, ModelFieldType.Phone, ModelFieldType.Email]
})
)
export class CustomTableFieldWidget extends BaseFieldWidget {
@Widget.Method()
public renderDefaultSlot(context): VNode[] | string {
const currentValue = this.compute(context) as string[];
return [createVNode(TableVue, { value: currentValue })];
}
}
Vue 组件:
// Table.vue
<template>
<div>{{ value }}</div>
</template>
<script lang="ts">
export default defineComponent({
props: {
value: {
type: String
}
}
});
</script>
通过这些自定义实现,你可以灵活地控制视图和字段的数据获取与修改,并且能够利用平台的 GraphQL 能力来实现更简便的数据操作。
Oinone社区 作者:汤乾华原创文章,如若转载,请注明出处:https://doc.oinone.top/frontend/18386.html
访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验