cancel
Showing results for 
Search instead for 
Did you mean: 

When do I need to declare multiple usages of the same component

Former Member
0 Kudos

I have a noddy WD4A component with a main view containing only ViewContainerUI elements. Each container has a sub-view embedded implementing some functionality I am playing with. One of these views implements a select option by using the WDR_SELECT_OPTIONS component. I have got this working. Then I decide to make a copy of the view in order to test some modifications. I embed this in a new ViewContainerUI element on the main view.

So now I have 2 sub views implementing the same select option. When I run it, the 2nd select option appears in the first view as a duplicate. The only way I can fix this is by declaring a second usage (of WDR_SELECT_OPTIONS) in the component and using this in the copied view.

So now I have 2 WDR_SELECT_OPTIONS component usages declared (with different names) so that my 2 views can coexist on the screen. Is this really necessary? Had it been the same view implementing both select options fair enough - but these are 2 different views.

If the views were not displayed at the same time, could I have declared and used just 1 component usage?

Peter

Accepted Solutions (0)

Answers (5)

Answers (5)

Former Member
0 Kudos

I have still not succeeded in dynamically creating a 2nd select Option and getting it to display in a View Container (called VC_SOD). The code compiles and runs but the select option does not display. This is hopefully something I will never need to do in reality. Just an exercise.

The code that is commented out is the original standard technique of using a select_option usage. There is probably more then 1 fundamental mistake in the code

method WDDOMODIFYVIEW .

DATA: LT_RANGE_TABLE TYPE REF TO DATA,

RT_RANGE_TABLE TYPE REF TO DATA,

READ_ONLY TYPE ABAP_BOOL,

TYPENAME TYPE STRING.

DATA: LR_COMPONENTCONTROLLER TYPE REF TO IG_COMPONENTCONTROLLER,

L_REF_CMP_USAGE TYPE REF TO IF_WD_COMPONENT_USAGE.

  • create the used component

L_REF_CMP_USAGE = WD_THIS->WD_CPUSE_SELECT_OPTIONS( ).

  • Here we copy the usage just for the hell of it.

DATA lr_component_usage type ref to if_wd_component_usage.

L_REF_CMP_USAGE = L_REF_CMP_USAGE->CREATE_COMP_USAGE_OF_SAME_TYPE( name = 'SELECT_OPTIONS2' ).

IF L_REF_CMP_USAGE->HAS_ACTIVE_COMPONENT( ) IS INITIAL.

L_REF_CMP_USAGE->CREATE_COMPONENT( ).

ENDIF.

*call the interface controller method init_selection_screen to get the helper class

  • WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS( ).

data L_INTF_CONTROLLER type ref to IWCI_WDR_SELECT_OPTIONS.

L_INTF_CONTROLLER ?= L_REF_CMP_USAGE->GET_INTERFACE_CONTROLLER( ).

**

data lo_view_controller type ref to if_wd_view_controller.

data lo_view_usage TYPE REF TO if_wd_rr_view_usage.

data lo_view_cnt_assignment TYPE REF TO if_wd_rr_view_cnt_assignment.

data lo_view type ref to if_wd_view.

lo_view_controller = wd_this->wd_get_api( ).

lo_view_usage = view->get_view_usage( ).

  • try and see what is going on

data lo_view_container_assignments type WDRR_VCA_OBJECTS.

lo_view_container_assignments = lo_view_usage->GET_VIEW_CNT_ASSIGNMENTS( ).

lo_view_cnt_assignment = lo_view_usage->create_view_cnt_assignment( name = 'VC_SOD' assigned_container = 'VC_SOD' ).

  • try and see what is going on

lo_view_container_assignments = lo_view_usage->GET_VIEW_CNT_ASSIGNMENTS( ).

  • init the select screen

  • WD_THIS->M_HANDLER = WD_THIS->M_WD_SOD->INIT_SELECTION_SCREEN( ).

WD_THIS->M_HANDLER = L_INTF_CONTROLLER->INIT_SELECTION_SCREEN( ).

WD_THIS->M_HANDLER->SET_GLOBAL_OPTIONS(

I_DISPLAY_BTN_CANCEL = ABAP_FALSE

I_DISPLAY_BTN_CHECK = ABAP_FALSE

I_DISPLAY_BTN_RESET = ABAP_FALSE

I_DISPLAY_BTN_EXECUTE = ABAP_FALSE ).

  • create a range table that consists of this new data element

LT_RANGE_TABLE = WD_THIS->M_HANDLER->CREATE_RANGE_TABLE( I_TYPENAME = 'S_CARR_ID' ).

  • add a new field to the selection

WD_THIS->M_HANDLER->ADD_SELECTION_FIELD( I_ID = 'S_CARR_ID' IT_RESULT = LT_RANGE_TABLE I_READ_ONLY = READ_ONLY ).

endmethod.

Former Member
0 Kudos

Hi

I am trying to dynamically create a 2nd select option Usage. Just for fun. But I get a compile error when I try and use it and I have no idea how to fix it. Can anyone help?

Peter

data L_REF_CMP_USAGE TYPE REF TO IF_WD_COMPONENT_USAGE.

  • create the used component

L_REF_CMP_USAGE = WD_THIS->WD_CPUSE_SELECT_OPTIONS( ).

  • Here we copy the usage just for the hell of it.

L_REF_CMP_USAGE = L_REF_CMP_USAGE->CREATE_COMP_USAGE_OF_SAME_TYPE( name = 'SELECT_OPTIONS2' ).

IF L_REF_CMP_USAGE->HAS_ACTIVE_COMPONENT( ) IS INITIAL.

L_REF_CMP_USAGE->CREATE_COMPONENT( ).

ENDIF.

*call the interface controller method init_selection_screen to get the helper class

  • WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS( ). " this works

WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS2( ). " compile error (Method does not exist) here

Former Member
0 Kudos

data L_REF_CMP_USAGE TYPE REF TO IF_WD_COMPONENT_USAGE.

* create the used component
L_REF_CMP_USAGE = WD_THIS->WD_CPUSE_SELECT_OPTIONS( ).

* Here we copy the usage just for the hell of it.
L_REF_CMP_USAGE = L_REF_CMP_USAGE->CREATE_COMP_USAGE_OF_SAME_TYPE( name = 'SELECT_OPTIONS2' ).

IF L_REF_CMP_USAGE->HAS_ACTIVE_COMPONENT( ) IS INITIAL.
L_REF_CMP_USAGE->CREATE_COMPONENT( ).
ENDIF.

*call the interface controller method init_selection_screen to get the helper class
* WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS( ). " this works
WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS2( ). " compile error (Method does not exist) 

You know, there is one small mistake in your coding.


 WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS( ). " this works

This can be executed, because:

You have declared the component usage "SELECT_OPTIONS" statically.

You can find the method in the by double clicking the "WD_THIS".


 WD_THIS->M_WD_SOD = WD_THIS->WD_CPIFC_SELECT_OPTIONS2( ). 

This can not be executed, because:

The component usage "SELECT_OPTIONS2" is declared dynamically.

It can only be available at runtime.

If you want to get the interface controller of "Select_options2", you should use:


 ** get the interface controller dynamicaly
    lr_interfacecontroller ?= L_REF_CMP_USAGE->GET_INTERFACE_CONTROLLER( ).

Hope it can help you a little.

Best wishes~

Former Member
0 Kudos

Hi

thanks for the tip on dynamically creating Usages using CREATE_COMP_USAGE_OF_SAME_TYPE. Googling this I found more info.

It seems one must declare a unique Component Usage for each view that uses the same component. (However I believe this is only necessary if the views are displayed/active at the same time).

By the way. It seems it is only possible to declare static Usages in the Component. Is there a reason for this? I can imagine it could be quite difficult to keep track of which views are using which Usages. Wouldn't it be more sensible to declare Usages in the Views?

Peter

PS Laha - What is your code going to achieve

Former Member
0 Kudos

Hi,

I think you can use "Clone Component Usage" or "Create Component Usage dynamically"

(1). For "Clone Component Usage"

You can use the following example simple coding:


DATA:
    lr_component_usage     type ref to if_wd_component_usage.

**Clone the component usage
    lr_component_usage = wd_this->GR_CMP_FLIGHT_USAGE->CREATE_COMP_USAGE_OF_SAME_TYPE( name = 'ALV_COMP' ).  "Here, you can replace "ALV_COMP" with your real component usage of WDR_SELECTION_OPTION

(2).For "Create Component Usage dynamically"

You can take a reference from the following example simple coding:


*   define component usage name
    CONCATENATE ls_flight-carrid
                ls_flight-connid INTO lv_cmp_usage_name
                SEPARATED BY '_'.

*   define embedding position name
    CONCATENATE 'V_MAIN/'
                lv_cmp_usage_name INTO lv_embed_pos.

*   add component usage to usage group
    lr_comp_usage = wd_this->gr_cmp_usage_grp->add_component_usage(
                               name               = lv_cmp_usage_name
                               embedding_position = lv_embed_pos
                               used_component     = 'SALV_WD_TABLE' ).
*   define dynamic navigation
    lr_view_api = wd_this->wd_get_api( ).
    lr_view_api->prepare_dynamic_navigation(
        source_window_name        = 'W_MAIN'
        source_vusage_name        = 'V_MAIN_USAGE_0'
        source_plug_name          = 'BOOKINGS_ALV'
        target_component_name     = 'SALV_WD_TABLE'
        target_component_usage    = lv_cmp_usage_name
        target_view_name          = 'TABLE'
        target_plug_name          = 'DEFAULT'
        target_embedding_position = lv_embed_pos ).
*   instantiate component usage if necessary
    IF lr_comp_usage->has_active_component( ) IS INITIAL.
      lr_comp_usage->create_component( component_name = 'SALV_WD_TABLE' ).
      lr_node_bookingtab = lr_flight_element->get_child_node( if_v_main=>wdctx_booking ).
      lr_interfacecontroller ?= lr_comp_usage->GET_INTERFACE_CONTROLLER( ).
      lr_interfacecontroller->set_data( r_node_data = lr_node_bookingtab ).
  ENDIF.

Good Luck to you.

krishnendu_laha
Active Contributor
0 Kudos

Hello,

Yes you can use one component usage for select option (as example mentioned).

Please see below code which you can add WDDOINT of those views:

DATA:
    lrf_cmp_usage            TYPE REF TO if_wd_component_usage.

* - Select-options
  lrf_cmp_usage =   wd_this->wd_cpuse_select_options( ).
  IF lrf_cmp_usage->has_active_component( ) IS INITIAL.
    lrf_cmp_usage->create_component( ).
 ELSE.
    lrf_cmp_usage->delete_component( ).
    lrf_cmp_usage->create_component( ). 
ENDIF.