编写详情组件
本组件代码可参看oak-generail-buiness/src/components/system/detail
现在,我们需要有一个组件对本System的信息进行读取并显示。在这里注意,在很多情况下,访问对象的过程是先get list获得满足条件的列表,再对其中的某一条数据进行get detail。但System对象比较特殊,它代表着当前正在访问的业务系统,因此不需要通过先设计list组件去查询其id,而是通过其它方法获得。我们先不关心这一过程具体如何实现,假设当前System的id已经得知。
逻辑层(index.ts)
在index.ts逻辑层,我们直接通过定义要访问的这条System数据的相关属性来获取它,代码大致如下:
export default OakComponent({
isList: false,
Entity: 'system',
projection: {
id: 1,
name: 1,
config: 1,
description: 1,
super: 1,
folder: 1,
},
formData({ data }) {
return data || {};
},
});
代码非常简洁直观,我们通过调用OakComponet来定义一个组件,组件访问的对象是System;此组件不是一个List组件,这意味着需要告知此组件要访问的数据行的id是多少(这是通过向组件传入OakId来实现的);在projection中定义要访问这行数据的属性有哪些,这里的属性明显和上面System对象的定义是保持一致的;最后在formData方法中,将取到的数据属性返回(提供给渲染层)。
通过这几行短短的代码,我们就已经实现了将一条System数据从后台取到前台的功能,接下来我们来渲染它。
渲染页面(web.pc.tsx)
在web.pc.tsx中,我们像下面这样来编写代码:
import React from 'react';
import { Tabs } from 'antd';
import { WebComponentProps } from 'oak-frontend-base';
export default function Render(props: WebComponentProps<EntityDict, 'system', false, {
id: string;
config: Config;
name: string;
style: Style;
}>) {
const { id, config, oakFullpath, name, style } = props.data;
const { t } = props.methods;
if (id) {
return (
// 利用name、stype等属性进行页面渲染
);
}
return null;
}
在Render函数的唯一参数props中,Oak框架将以WebComponentProps定义的格式,注入了两个属性:
- data: 在data中存放从逻辑层传递过来的数据,以及Oak框架的一些通用变量(例如上面代码中的oakFullpath,这类变量都以oak开头)。从逻辑层传递过来的数据则包括:
- formData中返回的数据(在上面的例子里,是从所取到的system行当中展开的属性)
- data和property中声明的数据。
- methods: 在methods中存放从逻辑层注入的方法,以及Oak框架注入的一些通用方法(例如上面代码当中的t方法,就是框架所注入的i18n方法)。其中,组件自身逻辑层注入的方法声明在OakComponent所声明的methods属性中。
使用组件
下面需要将上面的组件嵌入到系统的某一个页面当中。如果您在初始化项目时依赖了oak-general-business库,则这个组件已经被pages/console/system/config页面所引用。
在该目录下的web.pc.tsx中,可以看到如下代码(已进行简化):
import React from 'react';
import SystemPanel from 'oak-general-business/es/components/system/panel';
export default function Render(
props: WebComponentProps<
EntityDict,
'system',
false,
{
systemId: string;
}
>
) {
const { systemId, oakFullpath } = props.data;
if (oakFullpath) {
return (
<SystemPanel
oakId={systemId}
oakPath={`${oakFullpath}.system`}
/>
);
}
return null;
}
在这个页面上,我们将渲染oak-general-business所提供的system/panel组件(上面描述的system/detail组件是panel中的一个tab页,见下图),并传入了两个非常重要的参数:
- oakId:对于非List页面,都需要传入该行的ID,这里我们将当前的systemId传入(至于从哪里取到这个id的,可以参见同目录下的index.ts,在此不作展开)
- oakPath:对于所有关联Entity的组件,都需要指出它们在页面中的“路径”。在这个例子里,我们将SystemPanel组件放置在当前组件(其实是页面,其路径由oakFullpath所指代)的system子路径下。
关于页面和组件的“路径”规范及意义,我们将在todo章节详细解释。
现在,执行npm run start:web,运行项目后,进入 localhost:3000/console/system/config 页面,可以看到类似下面的效果:
