门户定制案例-顶部布局时自定义渲染内容
运行效果
设置门户布局为顶部菜单(top)风格,显示自定义左侧组织树选择组件,非顶部菜单(top)布局时不显示。
实现方法
- 定制企业门户应用,参考《门户定制》
- 在门户页 /entry/pcxapp/pcx/index.w 中,自定义内容渲染方法 layoutContentRender 的 after 扩展点,用代码添加“组织树”组件,实现在顶部菜单布局时内容渲染部分新增组织树组件。
- 添加自定义样式
- 添加“组织树”组件的 onSelect 事件,使用 history.router.emitter.emit 方法给其他页面派发事件
添加扩展点
桌面端门户的扩展点方法写在 /UI2/comp/portalConfig/components/portalConfig/portalConfig.config.pc.js 文件的 onConfigContextInit 方法中,如果没有 portalConfig.config.pc.js 文件,将 portalConfig.config.js 文件复制为 portalConfig.config.pc.js 文件
添加门户页 /entry/pcxapp/pcx/index.w 内容渲染方法 layoutContentRender 的 after 扩展点,代码如下
async onConfigContextInit(configContextProcessor) {
let _this = configContextProcessor.page;
let portalConfig = {
"config": {
"/entry": {
"/pcxapp": {
"/pcx": {
"/index.w": {
"layoutContentRender": {
"@after": (result,dom,props)=>{
return result;
}
}
}
}
}
}
}
};
merge(_this.configContext, portalConfig);
ConfigContextProcessor.enhancePageAdvice(_this);
}
- 使用 after 扩展点,在 layoutContentRender 执行完成后,对返回的数据进行定制,@after 的参数主要有2个
- result 参数:是方法 layoutContentRender 返回的数据
- args 参数:是方法 layoutContentRender 自带的参数(参数对应layoutContentRender方法中的参数)
- dom 参数:初始渲染内容
- props 参数:组件属性,来自this.state
添加“组织树”组件
在扩展点方法中添加组件,不能直接使用 W 文件中的源码,而需要使用后端编译过,能在 JS 上运行的代码。步骤如下
新建一个空白的页面,添加需要的组件并进行配置。如下图所示
配置完成后,预览页面,在浏览器中通过调试工具,获取该页面的编译内容。通过“文件名.component.js”获取"组织选择"编译后的 JS 代码,通过“文件名.bulid.js”获取“数据集”相关配置信息。具体使用参考完整代码中的说明
添加“组织树”组件,需要引入
import OrgTree from "$UI2/comp/antdpro/components/OrgTree/OrgTree.react";
import "$UI2/comp/antdpro/components/OrgTree/css/OrgTree.css";
添加“数据组件”,需要引入:
import RestData from "$UI2/wxsys/comps/restData/restData";
添加自定义样式
如果门户自定义有自定义样式,在自定义组件下新增 css 文件,在通过 import 进行导入,该案例所需 css 内容如下
.defined-layout-sider{
*{
white-space: nowrap;
}
.ant-tree{
background: transparent;
}
}
派发事件
使用事件派发 history.router.emitter.emit 对组件选择的数据进行分发,再使用事件派发接收方法 history.router.emitter.on(该方法可以放在需要组织数据处理页面上,支持跨应用使用),接收并根据业务进行数据处理。接收派发事件是根据“事件名称”进行接收的(事件名称支持自定义,只需要注意不要与现有的派发事件重复即可),例如本例的事件名称为:portalOrgTreeSelect
注意:在使用事件派发前需要先进行history引用
import history from "core/appHistory";
在组织树组件的点击选择节点事件中派发事件,代码如下
//组织树选择节点事件
const onSelect=(selectedKeys,extra)=>{
//事件派发,主要用于在其他页面接收点击选择的节点信息
history.router.emitter.emit("onPortalOrgTreeSelect", {selectedKeys,extra});
}
接收派发事件,代码如下,放在其他需要接收点击选择节点信息的页面中
history.router.emitter.on("onPortalOrgTreeSelect", ({ selectedKeys, extra}) => {
console.log(value);
});
完整代码
/UI2/comp/portalConfig/components/portalConfig/portalConfig.config.pc.js 文件的完整代码如下
import { merge } from "lodash";
import ConfigContextProcessor from 'core/framework/ConfigContextProcessor';
import {__expression} from 'core/utils';
import OrgTree from "$UI2/comp/antdpro/components/OrgTree/OrgTree.react";
import "$UI2/comp/antdpro/components/OrgTree/css/OrgTree.css";
import RestData from "$UI2/wxsys/comps/restData/restData";
import "./indexPortal.css";
import history from "core/appHistory";
import React from 'react';
export default {
processConfigContext(configContext) {
},
//自定义
async onConfigContextInit(configContextProcessor) {
//获取当前页
let _this = configContextProcessor.page;
//按照需要处理的文件路径及方法进行自定义
//@after:方法执行后执行;参数:(result,...args),其中result是方法返回数据,args是原方法自带参数
//@before:方法执行前执行;参数:(...args),其中args是原方法自带参数
//@replace:替换原方法;参数:(...args),其中args是原方法自带参数
//注意:上述3种方法,async标识必须与原方法同步,即原方法是异步,现在自定义方法才能使用异步,否则不能使用
//详细使用案例可以参考“帮助中心”下门户v2定制下相关案例
let portalConfig = {
"config": {
"/entry": {
"/pcxapp": {
"/pcx": {
"/index.w": {
"layoutContentRender":{
"@after":(result,dom,props)=>{
//防止一些特殊场景下出现多次渲染问题
if(result.key!="initLayoutContent"){
return result;
}
const {layout}=props;
//不是top类型返回初始元素
if(layout!="top"){
_this.state.contentStyle=null;
return result;
}
//top布局,需要设置内容模块样式
_this.state.contentStyle={padding:0};
//下面数据集配置需要的方法,从"组件页面.build.js页面上获取" (与实际数据集配置需要为准)
const $g_fns_restData0 = {
get _userdata(){
return wx.Util.prepareUserData(this, {
code: {
required: {val: function($self){
try{
return true
}catch(_$e){
return null;
}
}(this)}
}
}, ['orgID','forgID','typedID','id','parentID','name','code','fcode','fid','fname','sequence','seq','type','leaf','level','active','_sys_children_','_key']);
}
};
//创建组织数据集
const restData0Config = {
"schema":{
"limit":20,
"orderBy":[
{
"name":"sequence",
"type":1
}
],
"type":"array",
"items":{
"type":"object",
"props":{
"orgID":{
"define":"orgID",
"label":"主键",
"type":"string",
"extType":"String"
},
"forgID":{
"define":"forgID",
"label":"全路径主键",
"type":"string",
"extType":"String"
},
"typedID":{
"define":"typedID",
"label":"类型化标识",
"type":"string",
"extType":"String"
},
"id":{
"define":"id",
"label":"标识",
"type":"string",
"extType":"String"
},
"parentID":{
"define":"parentID",
"label":"父节点",
"type":"string",
"extType":"String"
},
"name":{
"define":"name",
"label":"名称",
"type":"string",
"extType":"String"
},
"code":{
"define":"code",
"label":"编码",
"type":"string",
"extType":"String",
"required":{
"expr":"true"
}
},
"fcode":{
"define":"fcode",
"label":"全路径编码",
"type":"string",
"extType":"String"
},
"fid":{
"define":"fid",
"label":"全路径标识",
"type":"string",
"extType":"String"
},
"fname":{
"define":"fname",
"label":"全路径名称",
"type":"string",
"extType":"String"
},
"sequence":{
"define":"sequence",
"label":"序列号",
"type":"string",
"extType":"String"
},
"seq":{
"define":"seq",
"label":"序号",
"type":"string",
"extType":"String"
},
"type":{
"define":"type",
"label":"组织类型",
"type":"string",
"extType":"String"
},
"leaf":{
"define":"leaf",
"label":"叶子节点",
"type":"integer",
"extType":"Integer"
},
"level":{
"define":"level",
"label":"层级",
"type":"integer",
"extType":"Integer"
},
"active":{
"define":"active",
"label":"状态",
"type":"integer",
"extType":"Integer"
},
"_sys_children_":{
"isCal":true,
"define":"EXPRESS",
"label":"子数据",
"type":"recursiveSelf"
},
"_key":{
"type":"string"
}
},
"key":"_key",
"fns":$g_fns_restData0
},
"id":"restData0",
"keyItems":"_key"
},
"options":{
"calcTotal":"",
"distinct":false,
"className":"/uaa/orgs",
"autoMode":"load",
"checkRange":"",
"tableName":"orgs",
"confirmRefreshText":"",
"allowEmpty":false,
"feature":{
"filter":true,
"subquery":true,
"distinct":true,
"paging":true,
"sort":true,
"join":true,
"fields":true,
"params":true
},
"confirmDeleteText":"",
"confirmRefresh":true,
"primaryColumns":[
"orgID"
],
"isReference":false,
"restResource":"class",
"isMain":false,
"directDelete":true,
"serviceName":"uaa",
"defSlaves":[],
"url":"/dbrest",
"confirmDelete":true,
"treeOption":{
"fullPaths":[
{
"name":"forgID",
"from":"orgID",
"separator":"/"
},
{
"name":"fcode",
"from":"code",
"separator":"/"
},
{
"name":"fid",
"from":"typedID",
"separator":"/"
},
{
"name":"fname",
"from":"name",
"separator":"/"
},
{
"name":"sequence",
"from":"seq",
"separator":"/"
}
],
"isTree":true,
"parent":"parentID",
"leafCol":"leaf",
"children":"_sys_children_",
"loadAll":false,
"fullId":"forgID",
"levelcol":"level"
},
"enableContextReadonly":true,
"checkMode":"",
"multiplePrimary":false,
"idColumn":"orgID"
},
"id":"restData0",
"filters":{}
}
//构建下面OrgTree所需要的restData0数据集,注意不要与门户页面上的数据集重复
let restData0 = _this.comp("restData0");
if (!restData0) {
restData0 = new RestData(_this, "restData0", restData0Config);
}
//组织树选择节点事件
const onPortalOrgTreeSelect=(selectedKeys,extra)=>{
//事件派发,主要用于在其他页面点击选择节点信息
history.router.emitter.emit("onPortalOrgTreeSelect", { selectedKeys,extra });
//接收派发事件,可以放在其他需要接收点击选择节点信息页面即可
// history.router.emitter.on("onPortalOrgTreeSelect", ({ selectedKeys,extra }) => {
// console.log(value);
// });
}
const $page=_this;
return <>
{/* 这里建议添加key,用于在某些特殊场景下判断使用 */}
<div key="defined-layout" className="defined-layout" style={{display:"flex",height: "calc(100vh - 60px)",}} >
<div className="defined-layout-sider" style={{width:"250px",padding:"10px",overflow:"auto"}}>
<OrgTree defaultExpandMode="root" blockNode="true" id="orgTree0" includeOrgKind="ogn,dpt,pos"
showIcon={true} showLine={true} titleColumn="name" listProvider="true" refDataId="restData0"
item="item" index="index" onSelect={onPortalOrgTreeSelect} items={
/* props */__expression(({restData0}) => {
return restData0.value;
},{$page},['restData0'])
}>
</OrgTree>
</div>
{/* 下面元素必须要新增“uix-portal-layout-content”class属性,否则会出现样式问题 */}
<div className="defined-layout-content" style={{flex:1,overflow:"auto"}} className={"uix-portal-layout-content"}>
{result}
</div>
</div>
</>;
}
}
}
}
}
}
}
};
//处理自定义内容
merge(_this.configContext, portalConfig);
ConfigContextProcessor.enhancePageAdvice(_this);
}
}