Skip to Content
avatar image
Former Member

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

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

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

5 Answers

  • avatar image
    Former Member
    Oct 12, 2010 at 02:52 PM

    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.

    Add comment
    10|10000 characters needed characters exceeded

  • Oct 09, 2010 at 02:44 PM

    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.

    Add comment
    10|10000 characters needed characters exceeded

  • Oct 11, 2010 at 04:28 AM

    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.

    Add comment
    10|10000 characters needed characters exceeded

  • avatar image
    Former Member
    Oct 11, 2010 at 07:18 AM

    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

    Add comment
    10|10000 characters needed characters exceeded

  • avatar image
    Former Member
    Oct 11, 2010 at 09:56 AM

    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

    Add comment
    10|10000 characters needed characters exceeded

    • 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~