• No results found

Multiple Usage of one Component

In document NET311 Advanced ABAP Web Dynpro (Page 105-115)

If multiple usages of the same component are required at runtime, but the number of usages is not known at design time, then the technique of dynamically cloning statically defined component usages can be applied.

Example: The user of a Web Dynpro application can mark multiple lines of a table to display details for each selected data set. The details of one data set is displayed by one usage of a certain component. Thus, the number of component usages

Figure 65: Multiple usage of one component: Example

The prerequisite for cloning any component usage is, that a single usage of this component has been defined at design time. Any controller having added the name of the static component usage to the list of used controllers / components can then create additional usages of the same component. Each component usage must have a unique name.

Figure 66: Multiple usage of one component: Cloning a statically defined component usage

To store the references to dynamically created component usages, a controller attribute may be used. In the ABAP Dictionary, the table type WD_COMPONENT_USAGE_GROUP has been created for this reason. The line type is a reference type to the interface IF_WD_COMPONENT_USAGE.

Alternatively, the framework supports managing dynamically created component usages by the concept component usage groups. This will be discussed in the section Dynamic Usage of different Components.

Figure 67: Prerequisites to create and store the references to a cloned component usage

To clone a statically defined component usage, the following steps are necessary: First, the reference to the statically defined component usage (<comp_usage_name>) has to be obtained using the method WD_THIS->wd_cpuse_<comp_usage_name>( ). This method is defined in the controller interface, since the name of the component usage has been added to its list of used controllers / components. Next, the method create_comp_usage_of_same_type( ) has to be called for the reference to the statically defined component usage. This will create an additional usage of the same component. The name of this additional component usage is defined via the method's parameter NAME.

Accessing the interface of a dynamically created component usage differs from the way presented for statically defined component usages. If the name of the component usage is known at design time, then the interface controller of this component usage can be added to the list of used controllers / components of any controller belonging to the consumer component. As a result, an additional method in the controllers generated interface is created (wd_cpifc_<comp_usage_name>(

)). Calling this method will return the reference to the component usage's interface controller. However, if the name of the component usage is not known at design time, this method does not exist in any controller. Thus, to access the interface controller of a dynamically defined component usage, the method get_interface_controller( ) has to be called for the reference to the related component usage. The receiving parameter of this method is of generic type ref

to object, thus casting this reference to a variable of the correct reference type is necessary before the functionality defined in the component's interface can be accessed.

Figure 68: Cloning a static component usage and accessing its interface controller

Embedding and Displaying an Interface View dynamically Up to now, embedding interface views have only been discussed for the case that the component usage related to the interface view has been defined at design time.

The single steps of embedding and displaying an interface view of a statically defined component usage are as follows:

In the consumer component, a view containing a ViewUIElementContainer is embedded in a window.

• In this window, the interface view of the used component is embedded in the ViewUIElementContainer of the previously embedded view.

• If the interface view must not be displayed before a certain user action (e.g.

clicking a button) takes place, the EmptyView has to be embedded in the ViewUIElementContainer, too. In addition, the EmptyView has to be defined

If the component usage is not defined at design time, it is not possible to embed an interface view of this component usage into a ViewUIElementContainer of another view. It is also not possible to define a navigation link connecting any outbound plug of an existing view to an inbound plug of this interface view at design time.

In this case methods of the Web Dynpro API have to be applied.

The API for view controllers and window controllers (interface

IF_WD_VIEW_CONTROLLER) contains the method prepare_dynamic_naviga-tion( ). This method allows to define a navigation link at runtime. In addition, it allows to define the embedding position for the target view (interface view) dynamically. After having called this method, the outbound plug of the source view has to be fired, so the navigation to the target view (interface view) is performed.

The embedding position for the view (interface view) is built up from the view's name <VIEW> and the name of the ViewUIElementContainer (<CONTAINER>):

<VIEW>/<CONTAINER>. For nested views, the further specification is separated by a period from the specification of the outer view / container combination:

<OUTER_VIEW>/<CONTAINER>.<INNER_VIEW>/<CONTAINER>

Hint: Calling the method prepare_dynamic_navigation( ) at runtime corresponds to creating a navigation link at design time. Thus, calling this method several times for the same outbound plug but different inbound plugs will have the same effect as defining multiple navigation links for the same outbound plug and different inbound plugs. This is only meaningful if each inbound plug belongs to a separate view and all of these views may be displayed in parallel (view assembly).

If the navigation could lead from one source view to different target views (e.g. depending on the user input) and the navigation link has to be defined dynamically, then one outbound plug should be created in the source view for each possible inbound plug in a target view. The correct outbound plug can be fired using the method fire_plug( <plug_name> ) defined in the interface IF_WD_VIEW_CONTROLLER.

Figure 69: Defining navigation link and embedding position dynamically

Handle Events of dynamically created component usages Up to now, handling events fired in the interface controller of a used component has only been discussed for the case that the component usage has been defined at design time. The single steps of registering an event handler method for an event are as follows:

• First, the controller firing the event has to be added to the list of used controllers / components of the controller that has to handle the event. For the case of cross component event handling, the controller to add is the interface controller of the used component.

Next, a method of type Event Handler has to be defined in the controller that should handle the event (Methods tab).

Using the value help for the field with the label Event right of the method's name, an event of the used controller can be assigned to the event handler method.

• After having selected the event handler, the signature of the event handler method is automatically changed to fit the signature of the event.

If the component usage is not defined at design time, then it is not possible to

signature of the event handler method can also not be defined in a way to fit the event's signature. However, registering an event handler method for an event can be performed at runtime using methods of the Web Dynpro framework.

Figure 70: Multiple usage of one component: Defining event handling dynamically

To dynamically register an event handler method of any controller belonging to the consuming component for an event of a component usage instance, the following steps have to be performed:

• First, the reference to the component usage instance has to be determined.

This reference is of type IF_WD_COMPONENT_USAGE.

For this reference, the method add_event_handler( ) has to be called.

Hint: The method remove_event_handler( ) can be used to delete the dynamic registering of an event handler method for an event.

Figure 71: Registering event handler method for event of used component dynamically

The signature of the event handler method is not modified by dynamically registering this method for the event of the used component. However, the complete information send by the event is available from the parameter WDEVENT that is predefined in all event handler methods. This parameter contains an internal table (WDEVENT->PARAMETERS) filled by the Web Dynpro runtime. For each parameter provided by the event, a line of this table is filled. Each line consists of the field NAME (filled with the name of the event parameter) and the field VALUE (filled with the value of the event parameter).

Because the type of each event parameter is arbitrary, the type of the value field is generic (type ref to data). Thus, before this value of a certain event parameter can be accessed, it has to be casted to a variable of the correct type. This is typically done by de-referencing the reference variable into a field symbol using the addition casting type <type_name>. However, the Web Dynpro runtime types the reference variables with dynamically generated types that are not compatible to the statically available types defined in the class builder. Thus a different way of de-referencing the variable value into a field symbol has to be used:

Figure 72: Dynamic event handling: Accessing the event parameters (1) At runtime, the type of a variable can be described by an object using RTTI (run time type information). On the other side, a RTTI type description can be used to type variables using the addition type handle to. This addition can also be used when de-referencing a reference variable into a generically typed field symbol (casting type handle to). Thus, accessing the event parameters involves the following steps:

• First the dynamically created reference type of an event parameter is obtained by using RTTI ( e.g. the method describe_by_data_ref( ) of class CL_ABAP_TYPEDESCR).

• Next, the parameter value is de-referenced in a field symbol using the addition casting type handle to <RTTI type object>.

• If the static type of this parameter is known, the field symbol can finally be casted to a reference variable of this static type.

Figure 73: Dynamic event handling: Accessing the event parameters (2)

In document NET311 Advanced ABAP Web Dynpro (Page 105-115)