- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
在上篇文章,我们已经设计了一个简单的设计态的Canvas,能够显示经过BuildEngine生成的ReactNode进行渲染。本文,我们将继续上一篇文章的成果,设计并实现一个能够显示组件节点大纲树的组件.
我们希望用户能通过一个地方比较明显的看到当前整个ElementNode的树状结构;当用户点击某个ElementNode的时候,既能够在DesignCanvas上高亮当前选中的UI元素,同时对于组件大纲树上也能高亮对应的树状节点.
PS:我们所设计的低开前端平台定位是轻量级。所以,我们在构建整个平台核心库的时候,并不会设计的非常复杂,本次我们将不会设计直接将元素进行拖拉拽到画布的内容,而是会围绕整个节点大纲树,来优化我们的低开体验.
在本次设计与开发之前,我们需要回顾一下上篇文章中( 低代码平台前端的设计与实现(三)设计态画布DesignCanvas的设计与实现 - 知乎 (zhihu.com) )关于DesignCanvas的设计。DesignCanvas的过程设计如下:
正如上图所示,DesignCanvas的执行过程中, step4 -> data5 -> step6 -> data7 是在一个函数处理过程中的.
为了实现本次的需求,我们可能需要对上述的过程进行一定的修改,达到UI的渲染与元素节点大纲树组件在同一个DesignCanvas中的渲染的目的。在讨论如何修改前,我们先采用一个流程图来展示这个过程:
从上图,我们可以很容易的知道,为了让ElementNode树到UI界面的生成与ElementNode树到节点大纲树的生成是一致且同步的。需要原本在DesignCanvas中渲染过程中,将ElementNode的JSON字符串解析为ElementNode节点数据,再把ElementNode数据交给BuildEngine生成ReactNode的这个 整体的步骤 ,拆分为两个先后两个步骤,并将ElementNode object作为state。这样,我们才能将ElementNode object分别交给节点大纲树组件进行节点树渲染,同时交给BuildEngine进行UI的ReactNode生成、渲染.
在这样一套设计下,无论点击大纲树任意树节点,还是点击设计态UI界面的任意UI组件。我们都能够通过相关的事件(对于大纲树来说是树节点的点击事件;对于设计态UI界面上的UI组件来说是前面设计的wrapper的点击事件)拿到当前点击的元素的唯一path标识;然后,我们将拿到的path标识设置给selectedElementNodePath这个state,最后再由该state来同时控制大纲树的节点高亮和设计态UI界面上的UI组件的边框高亮。这个过程由下面的流程图来简单描述:
首先,我们选择了antd5的Tree树形组件。对于该组件我们会以 受控 的方式来使用,具体来讲,Tree树形组件的 节点选中 通过属性 selectedKeys 控制;树形组件的 节点展开 通过属性 expandedKeys 来控制。当然,一旦我们选择该组件以受控方式使用,那么不可避免的需要用对应的 onSelect事件 和 onExpand事件 来获取当前状态值,再交给上述的 selectedKeys 和 expandedKeys .
本节内容主要讲antd5的Tree树形组件的基本用法,目的是为了后面我们具体的大纲树组件做基础准备,可以完全当作独立的一节内容来看.
Tree的selectedKeys接收的是一个数组,用以表现被选中的节点。但需要特别注意:
Tree在默认的使用场景下是 单个选中 。也就是说,用户点击任意一个节点时,就选中该节点;点击其他节点,则选中其他节点。同一时间只会有一个被选中的节点。 selectedKeys 尽管是一个数组,但在单选场景下,要不是一个空数组来表示没有节点选中,要不是一个只有一个元素的数组,表示某一个节点选中。下面用一个Demo来演示:
/**
* 首先准备一段测试数据:
* 1
* ├ 1-1
* └ 1-2
* └ 1-2-1
* 注意:TREE_DATA是一个数组!
**/
const TREE_DATA = [
{
key: '1',
title: 'title 1',
children: [{
key: '1-1',
title: 'title 1-1'
}, {
key: '1-2',
title: 'title 1-2',
children: [{
key: '1-2-1',
title: 'title 1-2-1'
}]
}]
}
]
然后,编写一段代码,将selectedKeys设置为 1-2-1 ,也就是说,我们选中了上面的 1-2-1 节点:
export const TreeDemo = () => {
return <Tree selectedKeys={['1-2-1']} treeData={TREE_DATA}/>
}
// 再次强调,selectedKeys是一个数组,但是在默认情况下,该数组只有一个元素或者空。
这个例子的效果如下:
从上面的gif可以看到界面渲染后,选中的节点就是 1-2-1 。同时,其他的节点无论我们如何点击,都不会有任何的效果(受控)。为了能够点击后,让Tree组件选中对应的节点,我们需要将 selectedKeys 至少作为一个state来存放,然后通过onSelect来设置该state:
export const TreeDemo = () => {
// 用一个state来表明当前选择的Keys
const [currSelectedKeys, setCurrSelectedKeys] = useState<string[]>([]);
return <Tree
treeData={TREE_DATA}
selectedKeys={currSelectedKeys}
onSelect={selectedKeys => {
// 当我们点击任何一个节点的时候,都会触发该onSelect,第一个参数则是即将选中的Keys
// 当然,根据文档,我们重复点击同一节点,也会触发该onSelect事件,但参数 selectedKeys 会是一个空数组
console.log('onSelect, selectedKeys: ', selectedKeys);
setCurrSelectedKeys(selectedKeys as string[])
}}
/>
}
上述的过程,可以用如下的数据流来描述:
上述过程中,currSelectedKeys表明当前选中的Keys(默认的单选模式下,是一个长度为1或0的数组),传给Tree的属性 selectedKeys ,Tree组件的UI展示的过程中使用根据 selectedKeys 来高亮对应节点;当然,我们点击任意节点的时候,会触发onSelect事件,该事件第一个参数就是点击选中的节点的Keys,我们可以直接将这个值再次设置给currSelectedKeys这个state。在上述的代码下,我们可以看到效果如下:
现在,我们分析了 selectedKeys 后,再来分析一下Tree树形组件的 expandedKeys 。这个属性是一个数组,控制整个Tree节点展开的Keys。我们首先将该值设置为: ['1'] :
... ...
return <Tree
treeData={TREE_DATA}
selectedKeys={currSelectedKeys}
onSelect={selectedKeys => {
... ...
}}
+ expandedKeys={['1']}
/>
然后查看Demo效果:
可以看到,无论怎样点击节点左侧的三角,都无法展开或收起对应的子节点。类似的,我们使用一个state来存储展开的节点,然后使用onExpand事件来设置,即可达到效果:
有了上面关于antd5的Tree树形组件的受控方式的使用基础,我们开始设计我们自己的组件大纲树组件,这里我们为它取名为: ElementNodeDesignTreePanel 。该组件的props如下:
interface ElementNodeDesignTreePanelProps {
/**
* 根ElementNode
*/
rootElementNode: ElementNode;
/**
* 选中的元素节点
*/
selectedElementNodePath: string;
/**
* 点击选中Tree中的某个节点的事件回调
* @param selectedPath 选中指定的ElementNode的Path,
* 譬如:"/page/panel@0/button@0"
* @param selectedPathList 选中的指定的ElementNode的完整链路Path列表
* 譬如:["/page", "/page/panel@0", "/page/panel@0/button@0"]
*/
onElementNodeSelected: (selectedPath: string) => void;
}
我们再来讨论下这些属性如何关联内部的antd Tree树形组件的渲染与行为的。这里,我直接用一个流程图来描述:
上述过程具体为:首先,为了呈现组件节点树状UI,很容易知道至少需要将ElementNode对象传入,因为该对象本身就是树形的,只需要进行简单的数据转换即可完成Tree的树形渲染;其次,为了达到高亮对应的节点效果,则需要传入当前选中的ElementNode的唯一path,在内部转换为selectedKeys和expandedKeys;最后,当我们点击Tree的节点时候,需要把对应的节点信息传到上层,让外部再次控制传入当前选中的ElementNode的path,形成一个闭环的数据流.
当然,这里面还涉及一些转换,还有path的构成规则。这里不再赘述,感兴趣的读者可以阅读有关 ElementNodeDesignTreePanel 的组件代码.
本次的内容已经提交至Github,并在打上了相应的Git tag标识:
https://github.com/w4ngzhen/lite-lc/tree/chapter_04 。
commit信息(倒序):
4. 修改DesignCanvas相关逻辑,实现ElementNodeDesignTreePanel组件与BuildEngine生成的组件对于选中的节点path,同步分别高亮树形节点和UI组件。
3. 新增工具方法,支持根据ElementNode的path,得到该节点的整个链路path形成的数组;新增ElementNodeDesignTreePanel组件,内部使用antd的Tree树形控件以呈现ElementNode的树状结构,且通过外部传入的"选中节点path"属性,以受控方式
控制高亮节点。
2. core/src/canvas下目录新增design目录,将存放于canvas目录下的DesignCanvas、ElementNodeDesignWrapper迁移至design目录,同步修改index中的DesignCanvas。
丰富example中的样例ElementNode Json字符串。
1. 1)core与example项目均升级antd至^5.2.0,antd5采用 CSS in JS方案,故移除antd相关样式文件;2)core项目tsconfig配置修改,跳过对antd等外部库的ts类型检查。
最后此篇关于低代码平台前端的设计与实现(四)组件大纲树的构建设计的文章就讲到这里了,如果你想了解更多关于低代码平台前端的设计与实现(四)组件大纲树的构建设计的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在 cordova@7.1.0、cordova-ios@4.5.2 下运行。安装平台:ios 4.5.2。 我运行 npm install、bower install,然后运行 cordova
我正在使用 VSTS 构建 IOS,运行命令后出现以下错误:cordova build ios 平台“android”似乎不是有效的 cordova 平台。它缺少 API.js。不支持安卓。 Cord
您使用什么软件/Wiki 来编写和分享有关开发人员、测试人员和管理人员的规范? 你使用维基系统,如果是,你使用什么维基软件? 或者您是否使用 Sharepoint 来管理和版本规范?将 SharePo
这是一家销售完整软件套件/平台的公司的示例 www.ql2.com/technology/platform.php 我想知道这样的套件/平台是如何开发的?你必须使用J2EE吗? 我更感兴趣的是这家公司
这个问题不太可能对任何 future 的访客有帮助;它只与一个较小的地理区域、一个特定的时间点或一个非常狭窄的情况相关,通常不适用于全世界的互联网受众。如需帮助使此问题更广泛适用,visit the
我有一个连接到套接字连接的应用程序,并且该连接向我发送了很多信息..可以说每秒 300 个订单(也许更多)..我有一个类(它就像一个监听器,对某个事件(并且该事件具有顺序)接收该顺序。创建一个对象,然
我即将开始一个 Netbeans 平台的项目。有没有人推荐他们用过并觉得有用的书籍或教程? 编辑: 这是一个已经开发好的swing应用。 最佳答案 除了 NetBeans 网站上的教程外,我还喜欢这本
有没有什么好的方法可以以非特定语言的方式定义接口(interface)/类层次结构,然后以特定语言生成相应的源代码?特别是,我需要同时针对 Java 和 C# 来创建一个相当全面的 API。我记得有一
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
大家晚上好我使用 API 平台,我想在创建实体时自动将所有者添加到我的实体中。我创建了一个事件来覆盖 API 平台,它获取当前用户并添加它。但是我的事件永远不会发生,但它确实存在于 debug:eve
这是一个有点奇怪的元编程问题,但我意识到我的新项目不需要完整的 MVC 框架,作为一个 Rails 人,我不确定现在该使用什么。 为您提供必要功能的要点;该网站将显示静态页面,但用户将能够登录并“编辑
这两天我的信息有点过载。 我打算建立自己的网站,允许本地企业列出他们的打折商品,然后用户可以进来搜索“Abercrombie T 恤”,然后就会列出出售它们的商店。 这是一个非常棒的小项目,我真的很兴
我的任务是为产品的下一代版本评估“企业”平台。我们目前正在考虑两种“类型”的平台——RAD(工作流引擎、集成 UI、工作流“技术插件”的小核心、状态的自动持久化……),例如 SalesForce.co
我需要一个不依赖于特定语言或构建系统的依赖管理器。我研究了几个优秀的工具(Gradle、Bazel、Hunter、Biicode、Conan 等),但没有一个能满足我的要求(见下文)。我还使用了 Gi
我在 Symfony 4 Flex 应用程序中使用 API Platform v2.2.5,该应用程序由一个功能 API 和 JWT Authentication 组成。 ,一些资源默认Open AP
虽然隐私法通常不属于我们开发人员的管辖范围,但我确实认为这是一个重要的话题,因为我们开发人员应该有责任警告我们的雇主,如果他们想要的东西会违反一些法律......在这种情况下,隐私法......通常情
我已经下载了 VisualVM 源代码,并尝试使用 Netbeans 7.01 编译 Glassfish 插件。这样做会导致以下错误: C:\source\visualvm\trunk\plugins
尝试 gradle 同步后...失败并在消息对话框中显示 Missing Android platform(s) detected: 'android-26' Install missing plat
大家好!我最近开始使用 Cordova,当我运行 Cordova platform add android 时,出现以下错误。我已经成功放置了 Java 和 Android SDK 的环境变量。但 n
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我是一名优秀的程序员,十分优秀!