二维码

[教程] TREE VIEW

Twilight发表于 2016-02-05 23:26lhx7300886 最后回复于 2017-03-03 09:12 [复制链接] 5018 1

TREE VIEW is used to represent hierarchical form of data.

Ex: organizational data in SAP CRM can be represented as tree view.
Tree node 7.jpg
In WEB UI terminology, there is no special view type for tree view as we have form view and table view. We can consider tree view is a special form of table view. There is no wizard available to create a tree view. We need to adapt existing view into table view by following certain manual steps.

At first, it looks difficult, but the more number of times you do it, the more you understand it. In this chapter, I am going to create a tree view that looks like below.
Tree node 8.jpg

As you see, it has two levels. First level will show the lead ID and next level will show its customer. I took this example for simplicity.

In order to follow this tutorial, we need to create one table view. I am not going to describe steps to create a table view as we had already covered it in the previous lessons. In this chapter,
I created one table view with base entity ‘BTQRLeadDoc’.

I created one context node with same type at component controller and I coded in the component controller’s method DO_INIT_CONTEXT to fetch the data.

Then I did component binding between the table view context node and the context node of component controller.  So data have been fetched in to our table view.  Below is the code that I wrote in the           DO INIT CONTEXT method of component controller.
  1. METHOD do_init_context.

  2.   DATA:lr_query TYPE REF TO cl_crm_bol_dquery_service,
  3.        lr_col   TYPE REF TO if_bol_bo_col,
  4.        lt_query_params  TYPE crmt_name_value_pair_tab,
  5.        ls_query_param   LIKE LINE OF lt_query_params.

  6.   "getting the query service.
  7.   lr_query ?= cl_crm_bol_dquery_service=>get_instance('BTQLeadDoc').

  8.   ls_query_param-name = 'MAX_HITS'.
  9.   ls_query_param-value = 10.
  10.   APPEND ls_query_param TO lt_query_params.

  11.   CALL METHOD lr_query->set_query_parameters
  12.     EXPORTING
  13.       it_parameters = lt_query_params.

  14.   lr_col ?= lr_query->get_query_result( ).

  15.   me->typed_context->lead->collection_wrapper->set_collection( lr_col ).

  16. ENDMETHOD.
复制代码

What I did?

I simply fetched first 10 lead records and feeding the context node LEAD with those records. As I did data binding between table view and context node of component controller, data will flow to the table view as well.

So we are all set and let’s begin the main part.

First, go to the table view context node implementation class and change its super class from ‘CL_BSP_WD_CONTEXT_NODE_TV’ to ‘CL_BSP_WD_CONTEXT_NODE_TREE’. If there is any Dialog box asking to redefinitions of certain methods, choose yes.
Tree node 1.jpg

This class provides two important methods

GET_TABLE_LINE_SAMPLE  and  REFRESH.

First method will return one structure based on which columns of view are decided.

REFRESH method is generally used to generate the first level of nodes or root nodes.
Tree node 2.jpg

Here I am using just two columns to display information. So go to GET_TABLE_LINE_SAMPLE and add two columns as required.
  1. METHOD get_table_line_sample.

  2.   TYPES: BEGIN OF line,
  3.           id        TYPE crmt_object_id,
  4.           prospect  TYPE crmt_prospect,
  5.          END OF line.

  6.   CREATE DATA rv_sample TYPE line.

  7. ENDMETHOD.
复制代码

Once this method is activated. Reopen the entire component using BSP_WD_CMPWB. Now you can see two columns in the view configuration tab. Move two columns from available section to displayable section and change the title accordingly and save the configuration.

We will come to REFRESH method later.

Now one important step is change the tag in .htm page. All tree views use the chtmlb: configTreeto display the tree view. Go to the .htm page and remove the existing CONFIGCELLERATOR or CONFIGTABLE tags and place the following tag and activate it.
  1. <%@page language="abap" %>
  2. <%@extension name="thtmlb" prefix="thtmlb" %>
  3. <%@extension name="chtmlb" prefix="chtmlb" %>
  4. <%@extension name="bsp" prefix="bsp" %>
  5. <chtmlb:configTree id                    = "ProductTree"
  6.                    nodeTable             = "<%= lead->node_tab %>"
  7.                    nodeTextColumn        = "ID"
  8.                    onCollapseNode        = "collapse"
  9.                    onExpandNode          = "expand"
  10.                    onRowSelection        = "select"
  11.                    selectionMode         = "<%= LEAD->SELECTION_MODE %>"
  12.                    selectedRowIndexTable = "<%= LEAD->SELECTION_TAB %>"
  13.                    selectedRowIndex      = "<%= LEAD->SELECTED_INDEX %>"
  14.                    type                  = "<%= CL_THTMLB_TREE=>GC_TYPE_COLUMN %>"
  15.                    usage                 = "ASSIGNMENTBLOCK"
  16.                    downloadToExcel       = "FALSE"
  17.                    noFrame               = "TRUE"
  18.                    personalizable        = "TRUE"
  19.                    table                 = "//LEAD/Table"
  20.                    visibleRowCount       = "20"
  21.                    xml                   = "<%= controller->configuration_descr->get_config_data( ) %>" />
复制代码

‘Lead’ in above tag is a context node.  
Property nodeTextColumn is used to choose which attribute will act as root of tree or fist column of tree. Here I chose ID column according to my requirement.
For node table property, we will send LEAD->NODE_TAB after filling it with required nodes.
We specified event handlers ‘collapse’ when we collapse a tree and ‘expand’ when we expand the tree for properties OnCollapseNode and onExpandNode.

Next, we need to create one class in SE24 with super class ‘CL_BSP_WD_TREE_NODE_PROXY’. This class offers one method called GET_CHILDREN. This method is used to create child nodes.
Tree node 3.jpg

Before activating the class, just redefine the GET_CHILDREN method and activate it.
Let us come back to the REFRESH method. Write the following code and activate it.
  1. METHOD refresh.

  2.   CALL METHOD super->refresh.

  3.   DATA:lr_entity    TYPE REF TO cl_crm_bol_entity,
  4.        lr_coll_wr   TYPE REF TO cl_bsp_wd_collection_wrapper,
  5.        lr_iterator  TYPE REF TO if_bol_bo_col_iterator,
  6.        lr_root      TYPE REF TO if_bsp_wd_tree_node.
  7.   TRY .
  8.       lr_coll_wr  ?= me->get_collection_wrapper( ).
  9.       lr_iterator ?= lr_coll_wr->get_iterator( ).
  10.       lr_entity   ?= lr_iterator->get_first( ).
  11.       WHILE  lr_entity IS BOUND.
  12.         lr_root = me->node_factory->get_proxy( iv_bo = lr_entity
  13.                                                 iv_proxy_type = 'ZCL_TREE_PROXY_MAIN' ).
  14.         "add the proxy to the node table of the tree
  15.         lr_root->node_key = add_root_node( lr_root ).
  16.         lr_entity ?= lr_iterator->get_next( ).
  17.       ENDWHILE.
  18.     CATCH  cx_sy_move_cast_error cx_sy_ref_is_initial.

  19.   ENDTRY.

  20. ENDMETHOD.
复制代码

Here we are simply looping each record of context node i.e. lead record and creating one node for each record using the GET _PROXY method of NODE_FACTORY. Then we are adding the root node to tree using method ADD_ROOT_NODE. In my scenario, above loop will create 10 root nodes as I fetched 10 lead records.

I am giving the class name we just created in se24 for proxy type. We are done creating root node but not displaying it. We need to manually add GETTER methods to proxy class to display any attribute on the tree.

Go to the proxy class ‘ZCL_TREE_PROXY_MAIN’ and copy the method IF_BSP_MODEL_SETTER_GETTER~_GET_XYZ and check the filter check box and paste it in the empty row. This process will copy all required import export parameters of the method. Then change the name to GET_ID. We just copied the GETTER method template and renamed it according to the attribute name.
Tree node 4.jpg
Tree node 5.jpg

Write the following code to get the ID of lead.
  1. METHOD get_id .

  2.   DATA:lr_entity TYPE REF TO cl_crm_bol_entity.

  3.   IF me->bo IS BOUND.
  4.     lr_entity ?= me->bo.
  5.     lr_entity->get_property_as_string( EXPORTING iv_attr_name = 'OBJECT_ID' RECEIVING rv_result = value ).
  6.   ENDIF.

  7. ENDMETHOD.
复制代码

First level node is creation and display is done. Next we need to take care of child (here it is customer) node. In order to create second level node, we need to code in the get_children method first proxy class. We will use one more proxy class to create each child node. Go to SE24 and create one more class as we did above.
Tree node 6.jpg

We need to display customer as well. Following the same procedure and add one getter method GET_PROSPECT and write the code as below.
  1. METHOD get_prospect .

  2.   DATA:lr_entity TYPE REF TO cl_crm_bol_entity.

  3.   IF me->bo IS BOUND.
  4.     lr_entity ?= me->bo.
  5.     lr_entity->get_property_as_string( EXPORTING iv_attr_name = 'PARTNER_NO' RECEIVING rv_result = value ).
  6.   ENDIF.

  7. ENDMETHOD.
复制代码

Main point, we need to remember is, we created GETTER methods in the proxy classes; they are not part context node class. Display of child node is done. We did not create it.
Now go to the first created proxy class ‘ZCL_TREE_PROXY_MAIN’ and code in the get children method.
  1. METHOD if_bsp_wd_tree_node~get_children.

  2.   DATA:lr_coll  TYPE REF TO if_bol_bo_col,
  3.        lr_coll2 TYPE REF TO if_bol_bo_col,
  4.        lr_entity  TYPE REF TO cl_crm_bol_entity,
  5.        lr_child TYPE REF TO if_bsp_wd_tree_node.

  6.   lr_entity ?= me->bo.

  7.   TRY .
  8.       CALL METHOD lr_entity->get_related_entity
  9.         EXPORTING
  10.           iv_relation_name = 'BTADVSLea'
  11.         RECEIVING
  12.           rv_result        = lr_entity.

  13.       IF lr_entity IS BOUND.
  14.         CALL METHOD lr_entity->get_related_entity
  15.           EXPORTING
  16.             iv_relation_name = 'BTOrderHeader'
  17.           RECEIVING
  18.             rv_result        = lr_entity.
  19.       ENDIF.
  20.       IF lr_entity IS BOUND.
  21.         CALL METHOD lr_entity->get_related_entity
  22.           EXPORTING
  23.             iv_relation_name = 'BTHeaderPartnerSet'
  24.           RECEIVING
  25.             rv_result        = lr_entity.
  26.       ENDIF.

  27.       IF lr_entity IS BOUND.
  28.         lr_entity->get_related_entities( EXPORTING iv_relation_name = 'BTPartnerAll' RECEIVING rv_result = lr_coll ).
  29.         IF lr_coll IS BOUND.
  30.           lr_entity ?= lr_coll->get_first( ).
  31.           WHILE  lr_entity IS BOUND.
  32.             lr_child = me->node_factory->get_proxy( iv_bo = lr_entity
  33.                                                     iv_proxy_type = 'ZCL_TREE_PROXY_CUSTOMER'
  34.                                                     iv_parent_proxy = me ).
  35.             lr_child->is_leaf = abap_true.
  36.             APPEND lr_child TO rt_children.
  37.             lr_entity ?= lr_coll->get_next( ).
  38.           ENDWHILE.
  39.         ENDIF.
  40.       ENDIF.

  41.     CATCH cx_crm_genil_model_error.

  42.   ENDTRY.

  43. ENDMETHOD.
复制代码

What I did?
Here we need to use some BOL programming in order to fetch the customer of Lead.  So I need to traverse through some relationships to reach the target entity BTPARTNER.  Here I am reading all partners of Lead.

Once I fetched all partners, I am looping over each partner and creating child node for it using the NODE FACTORY method and proxy class ‘ZCL_TREE_PROXY_CUSTOMER’ we created above.
Here once I created child node, I am setting the IS_LEAF property as TRUE because in my scenario CUSTOMER is the last level and after that I am not displaying any child to customer. So there won’t be any arrow mark next to the folder icon for child nodes.

Next create two event handlers with name collapse and expand in the view implementation class and write the following code.
  1. METHOD eh_oncollapse.

  2.   DATA:lr_event_ic  TYPE REF TO cl_crm_ic_tree,
  3.        lr_event_thtmlb  TYPE REF TO cl_thtmlb_tree.

  4.   FIELD-SYMBOLS:<fs_line> TYPE crmt_bsp_treetable_node.

  5.   TRY .
  6.       lr_event_ic ?= htmlb_event_ex.
  7.       typed_context->lead->collapse_node( lr_event_ic->row_key ).
  8.     CATCH cx_sy_move_cast_error.
  9.       TRY .
  10.           lr_event_thtmlb ?= htmlb_event_ex.
  11.           typed_context->lead->collapse_node( lr_event_thtmlb->row_key ).
  12.         CATCH cx_sy_move_cast_error.
  13.       ENDTRY.
  14.   ENDTRY.

  15. ENDMETHOD.
复制代码
  1. METHOD eh_onexpand.

  2.   DATA: lr_event_ic      TYPE REF TO cl_crm_ic_tree,
  3.         lr_event_thtmlb  TYPE REF TO cl_thtmlb_tree.

  4.   FIELD-SYMBOLS:<fs_line> TYPE crmt_bsp_treetable_node.

  5.   TRY .
  6.       lr_event_ic ?= htmlb_event_ex.
  7.       typed_context->lead->collapse_node( lr_event_ic->row_key ).
  8.     CATCH cx_root.
  9.       TRY .
  10.           lr_event_thtmlb ?= htmlb_event_ex.
  11.           typed_context->lead->expand_node( lr_event_thtmlb->row_key ).
  12.         CATCH cx_root.
  13.       ENDTRY.
  14.   ENDTRY.

  15. ENDMETHOD.
复制代码

As name suggests, these are triggered when you expand or collapse any node.

Last thing is we need to add little bit coding in the DO PREPARE OUTPUT method to call REFRESH method.
  1. METHOD do_prepare_output.

  2.   IF me->typed_context->lead->node_tab IS INITIAL.
  3.     me->typed_context->lead->refresh( ).
  4.   ENDIF.

  5.   CALL METHOD super->do_prepare_output
  6.     EXPORTING
  7.       iv_first_time = abap_false.

  8. ENDMETHOD.
复制代码

Now you can execute the application and see the output.  When we learn it first time, it seems too many steps, but in actually, it is not that much difficult.

Here if I want to display ‘address’ as child to ‘customer’, Then I need to create one more proxy class and write the code in the GET CHILDREN method of CUSTOMER proxy class by using BOL relations from customer to address and need to add one GETTER method to that proxy class to display the address. Don’t forget add one more column ‘address’ in the GET_TABLE_LINE_SAMPLE.
You can try it on your own. Hope it helps you and do refer this site to your colleagues if you think it deserves it.
回复

使用道具 举报

lhx7300886
厉害厉害,这个应该已经是高难度的了
回复 支持 反对

使用道具 举报

快速回帖

本版积分规则
您需要登录后才可以回帖 登录 | 注册有礼

快速回复 返回顶部 返回列表