Google+ Facebook Twitter MySpace SC

Friday, August 24, 2012

Data Binding, Context Mapping and Interface Methods


Data Binding, Context Mapping and Interface Methods


This starts with the presentation of the mechanism used to manipulate data between the context attributes and UI elements, mechanism called,in Web Dynpro,“data binding”. We continue with the mechanism of sharing data among the various controllers, which is realized by using different variants of context mapping. Finally, we highlight the importance of the interface methods required to access them “cross-component”.
In the last chapter, we have created context nodes and attributes in the context view.A node or attribute can be created in each context. When we create an attribute in the context view, this value is visible only in this context view. The mechanism for sharing data among different controllers is known as “context mapping”. A context mapping can be internal, when the nodes we map are within the same component, and external, when the mapping is cross-components.
Data Binding
Each UI element has certain properties. With data binding, we define which node or attribute from the context will act as a data source for an UI element property. To exemplify the data binding mechanism, we create a component named Y_DATABINDING with a view named V_BIND and a window W_DEFAULT.

Structure of Y_DATABINDING component
In context view, we create a context node STUDENT with the same dictionary structure YSTR_PERSON.
Structure of STUDENT node
We create a WD component that reads the user inputs in the attributes FIRSTNAME,LASTNAME and DATEOFBIRTH. When the user presses the “SHOW” button, these data are shown by means of TextView UI Elements.
Example of data binding
We have many possibilities to make a data binding. For example, we can:
(a) Create a “Container Form” for a context node
(b) Use the Web Dynpro Wizard
(c) Create data binding for each attribute
(a) To create a “Container Form”, we add a Group UI element and then, by rightclicking,we choose from the contextual menu “Create Container Form”.
Creating container form
After this, we can choose which context node we use for data binding and which type of UI Element is associated to each attribute
 As a result, the Framework generates for each context attribute an UI element InputField and a proper label, and makes the data binding between each UI element property (value) and the context attribute.
Data mapping among InputField UI Elements and the context attributes.
To create a “Container Form”, we can use each UI Element of container type.
(b) To create a data binding, we can use the Web Dynpro Wizard button(Fig) In case we use the Form option, the Framework generates a transparentContainer UI element that contains the UI elements that we have to choose inthe same way as we have shown at point (a).
Using wizard to create a form and the proper data binding
(c) To manually define a data binding for each attribute, we have to insert the proper UI Element and create data binding between an UI element property and a context attribute. We insert 3 TextView UI Elements and 3 Labels UI Elements.
Layout structure
We have to create the data binding between each text property of the TextView UI Element and the proper context attribute.
Data binding
We repeat this step until we make data binding among the text property of all the three UI Elements and the proper context attributes. Then,we insert a Button UI Element in the Group GRP_STUDENT_WRITE and add an action.
Inserting a button and adding an action
In this case, we don’t need to enter coding in the generated event handler method onactionshow. After creating an application for our component, we are ready to run it. The result is presented. At runtime, the context attributes are empty. After the user enters values and pushes the SHOW button, the context attributes are populated with these values.At design time, we realised a data binding among the TextView UI Elements and the same context attributes (Firstname, Lastname and Dateofbirth). This is the reason why these UI Elements show the values entered by the user in the Input-Fields UI elements.
Running the application
Context Mapping
So far, we have used only context attributes that were defined in the view context.When we want to share data among different controllers, we have to define a context mapping.
A context mapping can be an internal context mapping or an external context mapping. An internal mapping relationship can be defined between any pair of controllers within the same WD component, whereas the external mapping defines a mapping across the borders of a WD component.
Internal Context Mapping
As mentioned before, the mechanism for sharing data among different controllers within the same WD component is known as internal context mapping.For a better understanding of this mechanism, we create the same example from data binding, but in this case we create the two groups GRP_STUDENT_READ and GRP_STUDENT_WRITE, in different views. At runtime, we display the view V_VIEW1.When the user presses the “SHOW” button, we display the second view V_VIEW2. The WD component structure is presented.
WD component structure
We cannot create the context node in the view context, because we need the values of this attributes not only in the view V_VIEW1, but in the view V_VIEW2 as well.In this case,we create the node STUDENT in the context of component controller.In this way,through context mapping, we can access the context of the component controller via a view controller. Context mapping doesn’t cause the duplication of data.The nodes in the view controllers only hold a reference to the mapping context node from the component controller.
Internal context mapping
We firstly create the context node of the component controller. After this, we make a context mapping between the context of the view V_VIEW1 and the context node of component controller. As a result, the entire context node STUDENT is mapped. In the same way, we proceed to make a context mapping between the context of the view V_VIEW2 and the context of component controller.Consequently,we have to create the view layout for the views V_VIEW1,V_VIEW2 and the data binding.Data stored in the context of the component.
Context mapping
The mapping result
controller can be used within a view if we have firstly made a context mapping.The schematic representation is presented.
Intern context mapping, data binding
The lines between controllers symbolize the context mapping, and the lines between view controllers and the views layout symbolize the data binding. In the view V_VIEW1, we create the group GRP_STUDENT_WRITE and then we can use the view context to create a “Container Form”.Because we want to show both views in the same window,after the user presses the “SHOW” Button we use a ViewContainerUIElement.
View layout for V_VIEW1
We have to embed the view V_VIEW2 in the ViewContainerUIElement.
Embed view V_VIEW2
We have to embed the view V_VIEW2 in the ViewContainerUIElement (Fig.).
Embed view V_VIEW2
After creating an application,we can see the result. At runtime, the User Interface is the same as for the data binding (example – Fig.)The difference is the context mapping. In this case, the context is not defined in the view context, but in the context of the component controller, and can be accessed through context mapping. The data reside in the context node of the component controller context, and the context node of the views controller simply holds a reference to this.
External Context Mapping
External mapping is a cross-component mapping and can be directly mapping or reversely mapping. We can create an external context mapping if we have firstly declared a usage for the component that holds the respective context and the respective context node has been marked as interface.
Direct Mapping
As a briefly description of this kind of mapping, we can say that the external mapping of direct mapping type is a cross-component mapping in which the main component directly access the data (represented through the context structure) of the used component.
For a better understanding of this type of mapping, we create the same example for the internal mapping, but in this case we create two WD components. The component Y_EM_LAYOUT has two Views used to create the user interface.To hold the data entered by the user, we use the context node STUDENT.To be able to access this context node, we have to define a component usage. In WD, the component Y_EM_LAYOUT defines a usage of the component Y_EM_CONTEXT.
WD component structure
In real cases, a faceless component is useful if several components access the same set of data. This type of component can be used to create a model for a multicomponent application. We firstly create the context node in component controller of the component Y_EM_CONTEXT. We keep the same context node STUDENT, but in this case we create an interface node. If this node has not defined the interface type, we cannot access it from another component.
Context node structure
The component Y_EM_LAYOUT has two Views used to create the user interface. To hold the data entered by the user, we use the context node STUDENT. To be able to access this context node, we have to define a component usage. In WD, the component Y_EM_LAYOUT defines a usage of the component Y_EM_CONTEXT
Defining a Usage in a component
After the usage is defined, we have to create a controller usage in the component controller. We need to use the component Y_EM_CONTEXT, the component use (named CONTEXT) and, hence, we need the INTERFACECONTROLLER
Controller usage definition
The next step is to define a mapping. In this case, it is an external mapping, because the node we use to define the mapping is outside the component
Defining an external mapping
As a result, the entire context node is mapped.
The mapping result
In the Methods tab, we have to verify in the wddoinit( ) Hook Method if it is an instance of the used component. The coding from Listing shows how we can verify this and how can be created in case it doesn’t exist.
Checking an instance of the used component
 METHOD wddoinit .
 DATA:lr_cmp_usage TYPE REF TO if_wd_component_usage.
 lr_cmp_usage = wd_this->wd_cpuse_context( ).
 IF lr_cmp_usage->has_active_component( ) IS INITIAL.
 lr_cmp_usage->create_component( component_name =
 'Y_EM_CONTEXT').
 ENDIF.
 ENDMETHOD.
By using the method HAS_ACTIVE_COMPONENT of the IF_WD_COMPONENT_USAGE, we verify if the usage has an active component.If the component has already been initialized, the logic moves on otherwise, we create an instance of the component by using the CREATE_COMPONENT method of the same interface. We must ensure that the external component has been instantiated before the interface controller is accessed.
It is recommendable to create a usage for a component only in the moment we need it.In our little example, we have to create the usage in the wdDoInit Hook method, but,in case we use navigations plugs to navigate to a used component,it is recommendable to create the usage in the method used to fire the respective plug.
Further, we can proceed as in the previous example: we create an internal mapping between the context node of the component controller and the context view of the views V_VIEW1 and V_VIEW2. After this, we can create the data binding.All these are schematically presented. The line between WD components symbolizes the external direct context mapping, the lines between component controller and views controllers symbolize internal mapping, and the lines between view controllers and views layout symbolize the data binding.
Reverse Mapping
As a briefly description of this king of mapping, we can say that the external mapping of the reverse mapping type is a cross-component mapping in which the data (represented through the context structure) are put at our disposal by the main component.
To realise the screen based on them, we use the interface view of the used component.For a better understanding of this type of mapping, we create the same example from direct mapping,where we change only the implementation part. We create two WD components, named Y_EM_CONTEXT_RM and Y_EM_LAYOUT_RM. The WD components structure is presented. We define, in the component Y_EM_CONTEXT_RM, the context node STUDENT.This component has no view, because we embedded here the interface view
Schematic representation of an external direct mapping
WD components structure
of the component Y_EM_LAYOUT_RM.The component Y_EM_LAYOUT_RM implements the user interface, making usage of the component Y_EM_CONTEXT_RM required to have access to the STUDENT node. Schematically, all these are presented. We firstly create the context node in the component controller of the component Y_EM_CONTEXT_RM, by using the same context node STUDENT and interface node.
Schematic representation of an external reverse mapping
Interface node
The component Y_EM_LAYOUT_RM implements the user interface. In component controller, we create a node named STUDENT, with the same structure as the node STUDENT from the component controller of the component Y_EM_CONTEXT_RM.
After creating the node, we make an internal mapping, we create the user interface and make the data binding. Another solution is to copy the component Y_EM_LAYOUT and to make the proper changes. We can copy this component by right-clicking on the component name, and choose “Copy” from the contextual menu. We have to specify a name for the new component and a package where we want to save this component. We define a usage of the component Y_EM_CONTEXT_RM and create an external mapping, reverse mapping.
Interface node, Input element
Context structure after usage and mapping
After entering the coding required to verify if it is an instance of the used component, we can save and activate. For the next step, we go back to the component Y_EM_CONTEXT_RM, where we have to define a usage for the component Y_EM_LAYOUT_RM, required to be able to embed its interface view.
After this, we can embed the interface view of the component for which we have defined only the usage. The Framework generates a corresponding interface view when we create a window. This interface can be embedded by other component,after the usage was defined. To embed the interface view or windows of the Y_EM_LAYOUT_RM component, we proceed in the same way as for embedding the views.
Defining the usage
Y_EM_LAYOUT_RM component, we proceed in the same way as for embedding the views.
Embed operation
After entering the coding required to verify if an instance of the used component exists, we can save, activate and run the application.
Interface Methods
A method of a component controller can be marked as interface. In this way, it is possible to access it cross-component. This option is possible only for the methods applied to the component controllers. The methods that take place in Views orWindows can’t be marked as interface.
For a better understanding of this kind of methods, we expand the previous example. In this example, after the user enters values and presses the “SHOW” button, the context attributes of the node STUDENT of the component Y_EM_CONTEXT_RM are populated with these values. When we want to verify if the user have entered his first name, we have to define an interface method in the component controller of this component, a method that verifies if this attribute has a value or it is empty. For this purpose, we create the interface method named check_firstname().
Marking a component controller method as interface
We create this method in the component Y_EM_CONTEXT_RM, because there is the context node where the values are transferred after the user presses the “SHOW” button.
Method check_firstname implementation
 METHOD check_firstname .
 DATA lr_node TYPE REF TO if_wd_context_node.
 DATA ls_node TYPE if_componentcontroller=>element_student.
 DATA lv_firstname TYPE string.
 DATA lr_api_controller TYPE REF TO if_wd_controller.
 DATA lr_message_manager TYPE REF TO if_wd_message_manager.
 lr_node = wd_context->get_child_node('STUDENT').
 lr_node->get_attribute(EXPORTING name = 'FIRSTNAME'
 IMPORTING value = lv_firstname).
 IF lv_firstname IS INITIAL.
 lr_api_controller ?= wd_this->wd_get_api( ).
 lr_message_manager = lr_api_controller->get_message_manager( ).
 lr_message_manager->report_error_message(
 message_text = 'The Field First Name is empty!').
 ENDIF.
 ENDMETHOD.
We read the value of the FIRSTNAME attribute into the local variable lv_firstname.After this, we verify if this attribute has a value or it is empty. In case this attribute is empty, we want to show a message with the string ‘The Field First name is empty!’.In this case, we have used the method REPORT_ERROR_MESSAGE of interface IF_WD_MESSAGE_MANAGER. To generate a message, we can use the Web Dynpro Code Wizard.
Usage of Web Dynpro Code Wizard
Is not recommended this art of programming, where the language-specific text elements are entered in the source text. In this case, we have used the easy way and not the best one. In the Chap.10, we explain how we can create messages easy to use and translate, without more programming effort.
After this method is implemented, we have to go back to the component Y_EM_LAYOUT_RM. When the user presses the SHOW button, we have to call the method check_firstname from the component use. If a method is marked as interface, we can cross-component access it. This means that we can call it from our onactionshow event handler method after we define a usage at the view level.
Usage definition
The coding from Listing shows the implementation of onactionshow event handler method.
Method call in used controller
 METHOD onactionshow .
 DATA: lr_interfacecontroller TYPE REF TO yiwci__em_context_rm .
 lr_interfacecontroller = wd_this->wd_cpifc_context( ).
 lr_interfacecontroller->check_firstname( ).
 ENDMETHOD.
We can use Web Dynpro Code Wizard to generate this code.
Web Dynpro Code Wizard
Runtime

No comments:

Post a Comment