ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ABAP OO实现ALV_TREE树形控件:节点事件与按需加载完整实战

ABAP OO实现ALV_TREE树形控件:节点事件与按需加载完整实战 做ABAP开发的手里难免会攒几个高频组件的心得。报表输出、数据维护、批量处理GRID ALV用得多可一旦数据有层级关系——组织架构、物料BOM、科目表、销售区域下挂客户——GRID那套平铺展示就顶不住了硬把父子关系塞进一张二维表看起来累用起来更累。这时候ALV_TREE就该上场了。早些年写ALV_TREE大家习惯直接抄cl_gui_column_tree的老例程代码能跑就行。可SAP这些年把面向对象框架越推越深老式的函数式ALV和树控件新版本里维护越来越少团队内部做代码审查时OO写法也越来越受青睐。我自己的体会是用纯粹的面向对象方式去写ALV_TREE代码结构清楚后续扩展事件、扩展自定义按钮、接业务逻辑都比在函数式老代码里缝缝补补舒服得多。这篇东西我就拿一个完整的ABAP OO风格ALV_TREE例程来拆从类怎么选、节点怎么挂、事件怎么收到踩过的坑怎么填一步步讲清楚。不管是刚接手ALV_TREE的新人还是想从老式树控件迁移到OO方案的老开发都能直接照着落一套能跑的代码。你可别指望看完马上能写出多复杂的树但至少日常的树形展示、双击下钻、按需展开这些事是真能拿下。1. 为什么非要选ALV_TREE核心思路与选型拆解1.1 树形展示到底解决了什么问题普通GRID ALV数据是一行一行平铺的。你要看一个集团下面所有公司、每个公司下面所有部门的成本和预算平铺出来就是一大片汇总关系得靠眼睛去对着列找找错了还容易把明细当成汇总。ALV_TREE的逻辑和GRID完全不一样它把数据组织成节点。一个父节点可以挂多个子节点子节点下面还能再挂层层向下。节点有展开和折叠两种状态默认折叠起来想看哪一层展开哪一层屏幕空间利用率和信息抓取效率都高。具体到业务场景ALV_TREE适合的场景大致有三类层级主数据科目表、成本中心、利润中心组、销售组织架构、物料BOM这些天然就是父子结构。分类汇总下钻比如大区看省份、省份看客户、客户看订单每层都是上一层数据的汇总明细。配置选项列表某些配置界面左侧树做入口导航右侧屏幕放对应的操作区域。判断要不要用树就一句话数据本身有没有层级关系用户操作时需不需要先看结构、再点节点进入明细。没有层级硬做成树界面反而绕。1.2 面向对象封装到底比老写法强在哪SAP里实现树形展示其实有好几条路。老的cl_gui_column_tree、cl_gui_simple_tree更老的直接调函数构建树都能出效果。但用ABAP OO的方式来写最大的优势是事件处理。树这个控件不像GRID那样把事件集中在几个回调里节点的单击、双击、展开、收起、右键菜单全是事件驱动的。如果用函数式老写法事件回调要么塞在屏幕PBO里判断要么得反复维护一个巨大的内部表对应关系代码一多就乱。用OO方式每个事件对应handler类里的一个方法事件源绑定到树实例逻辑天然和界面代码分离。举个最简单的例子双击节点触发函数OO方式只需三步定义handler类、在handler类里写方法、用SET HANDLER注册。后面想加事件在类里加方法就行不用去老代码堆里找接口在哪。再说可维护性。OO方式下树实例、节点集合、字段目录、事件处理器都是独立的成员作用域清清楚楚。新同事接手代码看类的结构就能知道大概逻辑而函数式的老代码往往是一大坨FORM树实例挂在全局变量里改一个功能容易碰坏另一个。1.3 合理判断什么时候别硬上ALV_TREE写ALV_TREE前先泼盆冷水这个控件不是万能灵药。我见过不少项目其实数据就几十行平铺的报表非要挂个树结果用户找数据还得一层层展开反而别扭。树适合的是用户真的需要“先看结构、再进层级”的场景。另一个坑是性能。ALV_TREE底层节点管理比GRID重几万行节点硬塞进去界面滚动和展开会明显卡顿。如果数据量巨大层级又多AG上千万级的数据绝不适合直接挂树你得先想清楚是按需加载还是先聚合层级。还有一点树形结构里做增删改比GRID麻烦节点重排、层级变动、节点数据回写都需要额外逻辑。如果核心需求只是批量编辑GRID才是更顺手的方案。总之——树的优势在于“看结构”GRID的优势在于“改数据”选组件先盘清楚业务核心需求。2. 核心对象与类结构掌握这几个类就能玩转九成场景2.1 cl_gui_alv_tree与cl_gui_column_tree怎么选在ABAP OO的树控件里最容易混淆的就是cl_gui_alv_tree和cl_gui_column_tree。从类的继承关系看cl_gui_column_tree继承自cl_gui_alv_tree它把节点和列的关系处理得更丰富能列出多列数据——比如树节点是物料子节点下面还能显示数量、单位、日期这些列。而cl_gui_alv_tree相对简洁它最典型的用法就是节点文本作为主列层级结构一目了然。如果你只关心树的层级展示不需要每一行都显示五个字段cl_gui_alv_tree完全够用代码也更清爽。我的个人建议只需要层级文本导航用cl_gui_alv_tree简单直接。节点下面需要带的列信息比较多而且列数据要跟着节点动态展示用cl_gui_column_tree。旧项目用了cl_gui_column_tree继续沿用别为了换而换。其实两个类关键方法高度一致add_node、add_nodes、expand_node、collapse_node、set_table_for_first_display这些两边的签名基本一样。学会一个另一个几乎白送。2.2 节点与层级模型node_key才是树的灵魂树里最核心的概念是节点而操作节点的钥匙是node_key。这玩意就是一个字符型的唯一标识SAP在add_node时自动生成并返回给你。以后你要展开这个节点、收起、下钻、删除、刷新都得拿这个key来说话。 添加节点时必须在IMPORTING里拿node_key CALL METHOD gr_alv_tree-add_node EXPORTING i_rel_node_key lv_parent_key i_relationship cl_gui_column_treerelat_last_child i_node_text 华东区 IMPORTING e_new_node_key lv_node_key.这里i_rel_node_key是父节点的key如果你不传节点就挂在根上。i_relationship是节点和父节点之间的关系位置常用的有relat_last_child作为父节点的最后一个子节点、relat_first_child作为第一个子节点、relat_next_node与父节点同级的下一个节点、relat_prev_node与父节点同级的前一个节点。树的层级结构本质上就是通过维护这个父子key关系来建立的。你add_node的层级和关系传对了树形结构就自动出来了。想重排节点顺序比如把某个子节点插到最前面就用relat_first_child重新挂一次原有节点会顺序后移。节点本身还有几个常用属性通过is_node_info参数传类型是lvc_s_nodeiDATA: ls_node_info TYPE lvc_s_nodei. 父子节点的视觉区分 ls_node_info-isfolder abap_true. 是文件夹风格有展开收起的折叠图标 ls_node_info-expanded abap_true. 默认展开 ls_node_info-disabled abap_false. 是否禁用 CALL METHOD gr_alv_tree-add_node EXPORTING i_node_text 华东大区 is_node_info ls_node_info IMPORTING e_new_node_key lv_node_key.is_folder这个属性很重要。如果你不设置节点就是个普通的文本叶子前端不会给展开和收起的指示设置了is_folder才能挂子节点而且展开收起箭头才会出现。还有一个容易忽略的点同一棵树里的node_key是全局唯一的不会重复。所以你完全可以在一个透明的中间表里维护“父节点key-子节点key-业务数据”的映射关系后续做数据交互会方便很多。比如点击业务节点时通过node_key拿到业务主键再回数据库查明细这套思路在树形界面上非常常用。2.3 事件机制双击、单击、展开、右键响应链路树控件的事件比GRID复杂常用的这几个值得提前搞清楚node_double_click双击节点触发最常见的下钻事件。item_double_click双击某个具体列触发列模式下用得多。selection_changed选中节点变化时触发适合做右侧联动界面。expand_no_children展开一个没有子节点的节点时触发常用来做按需加载——用户点开哪一层才去数据库取哪一层的数据。node_context_menu_request右键菜单弹出前触发用来动态设置菜单项。ABAP OO里的事件处理套路是固定的CLASS lcl_tree_handler DEFINITION. PUBLIC SECTION. METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_alv_tree IMPORTING node_key. ENDCLASS. CLASS lcl_tree_handler IMPLEMENTATION. METHOD on_node_double_click. MESSAGE i000(0) WITH 双击节点: node_key. ENDMETHOD. ENDCLASS.事件方法传参数过来时有个坑要注意。node_double_click给的是node_key而item_double_click给的是node_key和column_name还带一个type参数区分是什么类型。不要硬把两个事件的方法写成同一个签名否则编译不过去。注册事件的代码通常在树实例创建成功后统一处理CREATE OBJECT gr_tree_event_handler. SET HANDLER gr_tree_event_handler-on_node_double_click FOR gr_alv_tree.如果你在程序里创建了多个树实例SET HANDLER必须指明FOR哪个实例否则事件会在所有实例上触发而这几乎总会导致逻辑混乱。3. 从零搭一个能跑的ALV_TREE例程完整步骤与代码拆解3.1 屏幕设计与准备工作我们做一个简单的例程用ALV_TREE展示“销售大区 → 城市 → 门店”的三层结构双击门店节点时提示门店编码和销售额。功能不大但层级关系、节点添加、事件响应、字段目录这些核心要素都能覆盖到。先在SE38建一个可执行程序然后进入屏幕编辑器画一个屏幕100。在屏幕上放一个Custom Container控件给它起个名字我这儿叫TREE_CONTAINER。这个名字要记牢后面创建容器实例时要用。程序顶层声明的变量REPORT ztest_alv_tree. DATA: gr_container TYPE REF TO cl_gui_custom_container. DATA: gr_alv_tree TYPE REF TO cl_gui_alv_tree. DATA: gr_tree_handler TYPE REF TO lcl_tree_handler. DATA: gv_okcode TYPE sy-ucomm. DATA: gt_fcat TYPE lvc_t_fcat.这里整个树控件实例挂在全局变量gr_alv_tree上是因为屏幕每次PBO都要调用树实例如果实例放在子程序里刷新数据时很容易丢失。全局成员变量虽然老派但在这个场景下最可靠。3.2 PBO构建容器与树实例树的创建放在PBO模块里但必须做存在性判断。ABAP的事务和屏幕逻辑有个特点用户操作一次就会触发一次PBO如果每次PBO都重新创建树界面会狂闪用户体验很差。MODULE pbo_0100 OUTPUT. IF gr_container IS INITIAL. 第一步创建容器 CREATE OBJECT gr_container EXPORTING container_name TREE_CONTAINER. 第二步创建树实例 CREATE OBJECT gr_alv_tree EXPORTING parent gr_container node_selection_mode cl_gui_column_treenode_sel_mode_single item_selection abap_true no_html_header abap_false no_toolbar abap_false. 第三步注册事件 CREATE OBJECT gr_tree_handler. SET HANDLER gr_tree_handler-on_node_double_click FOR gr_alv_tree. 第四步初始化字段目录 PERFORM build_fieldcatalog. 第五步填充数据并构建树 PERFORM build_tree. ENDIF. ENDMODULE.node_selection_mode是节点选中模式node_sel_mode_single是单选node_sel_mode_multi是多选。如果你要支持用户按住Ctrl多选节点后批量提交就改成多选模式。no_toolbar这个参数如果你有自定义节点操作按钮通常要保留工具栏为真然后往Toolbar里加自己的菜单项。3.3 字段目录树的列怎么规划ALV_TREE里也是有列的。树的主层级列显示节点文本但除了层级列我们还能给每个节点带额外的列数据比如门店编码、销售额、更新时间。FORM build_fieldcatalog. DATA: ls_fcat TYPE lvc_s_fcat. 节点主列 ls_fcat-fieldname NODE_TEXT. ls_fcat-coltext 节点名称. ls_fcat-outputlen 30. APPEND ls_fcat TO gt_fcat. 业务列 CLEAR ls_fcat. ls_fcat-fieldname CODE. ls_fcat-coltext 编码. ls_fcat-outputlen 15. APPEND ls_fcat TO gt_fcat. CLEAR ls_fcat. ls_fcat-fieldname AMOUNT. ls_fcat-coltext 销售额. ls_fcat-outputlen 15. ls_fcat-do_sum abap_true. APPEND ls_fcat TO gt_fcat. CALL METHOD gr_alv_tree-set_table_for_first_display CHANGING it_fieldcatalog gt_fcat. ENDFORM.字段目录的定义和GRID ALV几乎一样都是lvc_s_fcat结构。如果是团队老项目工具栏上已经有一套构建fcat的标准函数可以直接复用到树上来省不少事。唯一要注意的是树必须有一个列对应节点文本列。如果你把NODE_TEXT这个列删了树的主层级列就没了界面会立刻出问题。3.4 add_node构建三层树结构构建树的核心动作就是一个一个add_node。这里我直接用业务数据模型来驱动在实际项目中最常见的数据来源是层级表或递归语句但逻辑套路是一样的。FORM build_tree. DATA: lv_root_key TYPE lvc_nkey. DATA: lv_east_key TYPE lvc_nkey. DATA: lv_beijing_key TYPE lvc_nkey. DATA: ls_node_info TYPE lvc_s_nodei. DATA: lt_nodes_plan TYPE TABLE OF lvc_s_nkey. 根节点 ls_node_info-isfolder abap_true. ls_node_info-expanded abap_true. CALL METHOD gr_alv_tree-add_node EXPORTING i_node_text 整体销售网络 is_node_info ls_node_info IMPORTING e_new_node_key lv_root_key. 一级节点华东区 ls_node_info-isfolder abap_true. ls_node_info-expanded abap_true. CALL METHOD gr_alv_tree-add_node EXPORTING i_rel_node_key lv_root_key i_relationship cl_gui_column_treerelat_last_child i_node_text 华东区 is_node_info ls_node_info IMPORTING e_new_node_key lv_east_key. 二级节点上海、杭州 ls_node_info-isfolder abap_false. CALL METHOD gr_alv_tree-add_node EXPORTING i_rel_node_key lv_east_key i_relationship cl_gui_column_treerelat_last_child i_node_text 上海总部 is_node_info ls_node_info IMPORTING e_new_node_key lv_beijing_key. 继续添加杭州等其他节点.... ENDFORM.这里有一个细节要提醒add_node方法里i_node_text传的是节点显示的文本但这个文本同时也决定了树的“列值”展示。后面我们想给节点挂业务数据编码和销售额只靠i_node_text是不行的。需要用另外一套机制把业务数据行和节点关联起来。3.5 给节点挂业务数据节点行绑定ALV_TREE的常规数据挂法是在add_node时把当前节点的数据行告诉树让树在做列展示时去内部表里找对应行的数据。具体操作先定义一张输出内部表gt_outtab结构包含节点文本、编码、销售额等字段。add_node时通过参数is_node_table_line传入当前节点在内部表里的行索引。DATA: ls_outtab TYPE ty_output. DATA: ls_node_table_line TYPE lvc_t_nkey. 组织行数据 ls_outtab-node_text 上海总部. ls_outtab-code SH001. ls_outtab-amount 1500000. APPEND ls_outtab TO gt_outtab. 记录当前节点的行索引 ls_node_table_line-line lines( gt_outtab ). CALL METHOD gr_alv_tree-add_node EXPORTING i_rel_node_key lv_east_key i_relationship cl_gui_column_treerelat_last_child i_node_text ls_outtab-node_text is_node_table_line ls_node_table_line IMPORTING e_new_node_key lv_node_key.is_node_table_line的类型是lvc_t_nkey这个结构比较冷门其实就是个行号的封装不要自己去拼。这样节点显示文本和业务数据行就绑定了树在渲染列信息时会自动根据内部表的行号把CODE、AMOUNT对应过去。不过说实话这个绑定方式在复杂场景下不够优雅因为你得自己维护行索引和节点key的对应关系。我自己的习惯是把node_key和业务主键维护在一张透明的节点映射表里。节点展示用i_node_text节点背后的业务逻辑用映射表代码看着更清楚后面想对节点做增删改也方便。3.6 事件响应双击节点下钻最后把事件响应接上。双击节点时我们通过node_key去映射表里查业务数据然后弹消息或者触发其他业务操作。CLASS lcl_tree_handler DEFINITION. PUBLIC SECTION. METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_alv_tree IMPORTING node_key. ENDCLASS. CLASS lcl_tree_handler IMPLEMENTATION. METHOD on_node_double_click. DATA: lv_code TYPE char10. 从映射表里根据node_key找业务编码 READ TABLE gt_node_map INTO DATA(ls_map) WITH KEY node_key node_key. IF sy-subrc 0. MESSAGE i000(0) WITH 双击节点 ls_map-code. ENDIF. ENDMETHOD. ENDCLASS.到这里一个最基本的ALV_TREE就完成了。屏幕运行起来左侧是三层树二三级节点默认展开下面有编码和销售额的列双击节点弹消息。这套骨架已经能应对相当一部分开发需求了。4. 进阶处理展开顺序、图标控制与按需加载4.1 节点展开与折叠的艺术树节点什么时候展开、什么时候折叠直接影响用户体验。默认情况下所有节点都是折叠的。如果你的树层级比较多用户要一层一层点下去烦都烦死。有两种办法控制展开状态一是在add_node时设置is_node_info-expanded abap_true节点创建后自动展开。二是程序运行过程中动态展开 展开所有节点 CALL METHOD gr_alv_tree-expand_all. 展开某个节点 CALL METHOD gr_alv_tree-expand_node EXPORTING i_node_key lv_node_key.但我得提醒一句expand_all在节点数量大的时候会非常卡特别是深层级、上百个节点时前端要一次性渲染用户能看到界面明显停顿。我建议默认只展开到一层或两层然后让用户自己去展开。如果业务要求默认全部展开先确认节点规模几千个节点全展开后页面性能真的扛不住。还有一个折中方案只展开根节点和第一层子节点第二层以后折叠。这样用户进来能看到全貌想看明细再往下点。 根节点下面一层自动展开 LOOP AT lt_top_nodes INTO DATA(ls_top). CALL METHOD gr_alv_tree-expand_node EXPORTING i_node_key ls_top-node_key. ENDLOOP.4.2 节点图标文件夹和叶子区分开树节点能不能带图标能。通过is_node_info里的image字段指定SAP的图标名就是ICON_开头那些效果比纯文字生动得多。比如父节点用文件夹图标ICON_FOLDER叶子节点用文档图标ICON_TEXT业务节点用对应业务的图标。DATA: ls_node_info TYPE lvc_s_nodei. ls_node_info-isfolder abap_true. ls_node_info-expanded abap_true. ls_node_info-image icon_folder. 文件夹图标 CALL METHOD gr_alv_tree-add_node EXPORTING i_node_text 华东区 is_node_info ls_node_info IMPORTING e_new_node_key lv_node_key.图标命名去SE16N查表ICON或者直接看标准程序里的ICON_前缀常量比瞎写快。这里还要留意如果叶子节点也想显示图标把is_node_info里的image一起带上就行isfolder照样设abap_false。4.3 按需加载节点多也不卡的终极方案节点数量一旦破万一次性add_node会卡到怀疑人生。正确的姿势是配合事件expand_no_children做按需加载。核心思路是先只添加根节点和一级节点当用户展开某节点时如果这个节点还没有子节点事件触发这时后台再去数据库查它的直接下级add_node挂上去。CLASS lcl_tree_handler DEFINITION. PUBLIC SECTION. METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_alv_tree IMPORTING node_key. ENDCLASS. CLASS lcl_tree_handler IMPLEMENTATION. METHOD on_expand_no_children. 根据node_key判断展开的是哪个父节点 查询数据库获取该父节点下的直接子节点 逐个add_node挂到node_key下 ENDMETHOD. ENDCLASS.按需加载写好后树的响应速度会显著提升因为前端一次只需要渲染几十个节点性能完全没问题。只是后端查询逻辑要设计好最好一次把某节点的直接子节点全查出来别用户展开一次你查一次数据库那也慢。我自己的做法是在节点映射表里加一个字段记录“是否已加载下级”展开时先判断避免重复加载同一层级。5. 我踩过的那些坑常见问题与排查心得5.1 节点不显示展开箭头加不上子节点这是新手最常见的问题。节点看起来是文本后面没有展开折叠箭头怎么加子节点都没反应。原因基本是add_node时没设is_node_info-isfolder abap_true。不设这个属性节点就是一个纯叶子前端认为它下面不可能再有子节点所以不给箭头。就算你后面硬挂节点上去界面也不显示。解决父级节点创建时is_node_info里的isfolder一定要设为abap_true。5.2 双击事件没触发或者触发两次双击事件不触发先检查SET HANDLER有没有写FOR gr_alv_tree。如果你的程序里有多个树实例而SET HANDLER写成了FOR ALL INSTANCES或者漏掉了FOR事件就会绑定到所有树上或者一个事件被处理多次。触发两次的情况通常是同时注册了node_double_click和item_double_click而两个HANDLER方法里又调了同一个处理逻辑。二选一注册别同时挂。5.3 节点数据刷不出来列空白fcat定义了字段但列没数据十有八九是is_node_table_line没传。节点文本是文本业务列是从内部表按行取的没绑定行关联树就去内部表里找不到对应行。解决add_node时把该节点对应的内部表行索引通过is_node_table_line传进去。这里有个细节内部表行索引必须和字段目录里的字段对应的输出表一致别搞混了表。5.4 工具栏按钮不显示或点了没反应树控件有自身工具栏想加自定义按钮得用set_toolbar_interactive或者往工具栏菜单里加条目。加上之后按钮触发的事件是toolbar_command和user_command。自己的按钮码要注册到user_command事件里处理漏了注册按钮点击确实会触发界面动作但程序里没有响应方法感觉就像点了没反应。5.5 排序问题树根本不听你排GRID里双击列头可以自动排序树的列头点排序通常会失效或者只在同级节点里部分排序。树的层级是核心随便打乱层级父子的顺序结构就乱了。如果你想做树的按名字排序建议在add_node阶段就控制好添加顺序。比如查询SQL里ORDER BY排好序然后顺序add_node树显示出来的自然是有序的。想事后调整用add_node里i_relationship参数把节点移动到指定位置但节点多的时候移动效率很低不如源头就排序。5.6 节点数量大导致的性能瓶颈之前做项目哪里没有按需加载直接一次性把几千个节点全塞进去。结果用户展开的时候前端要处理几千个DOM节点页面明显卡顿甚至浏览器崩溃。后来经过改造用按需加载一次只加载一级流畅很多。经验是层级多节点多一定按需加载。如果业务要求一进来就想看到全树的样貌那优先考虑减少展示数据量——比如先汇总到二级用户点开再去查明细。5.7 节点增删改后的刷新策略树控件不像GRID那样直接刷新内表就完事得多看一下。你改了底层数据后要么删除节点重建要么用update_node方法刷新。直接刷新内部表树界面不会自动同步。我习惯的增量增删节点的方式在节点映射表里维护好“业务主键 → node_key”的对应关系。新增数据时先找到该数据所属父节点的node_key然后add_node挂上去同步记录新的node_key。删除数据时先根据业务主键找到node_key用delete_node删掉再清理映射表。这个映射表的维护看起来多了一个步骤但后续做勾选、双击、下钻、数据回写都会方便很多。6. 个人经验补充写ALV_TREE时我坚持的几条规矩最后一个部分聊几句我这些年写ALV_TREE的体会。第一凡是树结构我一定先把“节点映射表”设计出来。这个表里维护node_key和业务数据主键的对应关系最好还带上父节点层级文本。前期多写几行定义代码后面做事件响应、数据刷新增删改查都会顺很多。第二树控件实例的创建全局成员变量不可怕可怕的是每次PBO都新建。我见过不少同事在这个环节踩坑屏幕闪屏、节点丢失、事件失效大多根因都在“实例没有被正确复用”。我自己的写法是容器创建后判断树实例是否为空为空才建不为空就复用收工。第三ALV_TREE真正好用的姿势是分级加载别把整棵树的节点都倒进前端。即使数据量不算大这个习惯也值得养成后续数据结构复杂了代码不用推倒重来。第四树的文本和业务展示要分开。节点文本自有它的展示规律比如要不要加图标、要不要加动画这是树控件的事。业务数据怎么查、怎么做权限控制这是程序逻辑的事。两者混在一起代码的耦合度会变高后期维护成本会上来。最后分享一个小技巧做树形界面开发先快速用静态数据把树的骨架搭出来验证节点层级和事件链路没问题再接真正的查询和业务逻辑。这样排障范围小定位问题快。我在新接手的项目里凡是碰到原有的树形报表崩得厉害都会先做这一步把树的结构重新缕清再逐步替换数据源。ALV_TREE这个组件说复杂它有一堆参数和事件要处理说简单把add_node、事件注册、节点刷新这三件事玩明白绝大多数业务场景就都能hold住。希望这篇例程拆解能帮你少走点弯路。
返回列表