cancel
Showing results for 
Search instead for 
Did you mean: 

Create LinkToAction with Image by run time

Former Member
0 Kudos

Hi,

I want to create linkToAction UI's with different images by run time. But if I try the code below I get always the same image for every linkToAction UI. What is my mistake? And how can I solve this problem?


	for (int i = 0; i < wdContext.nodeGlob_Struc().size(); i++){
	   
	     IWDLinkToAction linkToAction = (IWDLinkToAction) 
	          view.createElement(IWDLinkToAction.class, "linkToAction"+i);
					
	     IPrivateDocPreAppView.ILinkToActionElement nodeLink = 
                  wdContext.createLinkToActionElement();				
 	     wdContext.nodeLinkToAction().bind(nodeLink);	
			
	     wdContext.currentLinkToActionElement().setImageSource(
   	          wdContext.nodeGlob_Struc().getGlob_StrucElementAt(i).
                       getUrl_Thumbnail() );
			
	     linkToAction.bindImageSource( wdContext.nodeGlob_Struc().
                   getNodeInfo().getAttribute(IGlob_StrucElement.URL__THUMBNAIL) );	

            theGroupBox.addChild(linkToAction);
        }



regards,

Sharam

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

What's node "LinkToAction" good for?

If I understand correctly, you want to create as many LinkToAction elements as you have elements in node "Glob_Struc", and the image source is taken from an attribute of its node elements.

Try this code:

    final IGlob_StrucNode node = wdContext.nodeGlob_Struc();
    for (int i = 0; i < node.size(); i++)
    {
      IGlob_StrucElement e = node.getGlob_StrucElementAt(i);
      IWDLinkToAction linkToAction = (IWDLinkToAction) view.createElement(IWDLinkToAction.class, null);
      linkToAction.setImageSource(e.getUrl__Thumbnail());
      theGroupBox.addChild(linkToAction);
    }

Armin

Answers (1)

Answers (1)

BeGanz
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hallo Sharam,

The Web Dynro binding model does not support "index binding". This means binding multiple image UI elments to the same attribute in a multiple context node (cardinaltiy 1..n) means, that all images are bound to the node's lead selection. That's what you implement with

 linkToAction.bindImageSource( wdContext.nodeGlob_Struc(). getNodeInfo().getAttribute(IGlob_StrucElement.URL__THUMBNAIL) );

Armin's solution is based on the fact, that he breaks the data binding principle by directly setting the imageSource property values.

Sharam, when reviewing your code I find several "problems":

1. Never ever store UI elements in the context. I assume you do this in order to access UI elements outside wdDoModifyView() as it is static. There is no need to do this.

2. Then you break databinding by setting the imageSource property in the linkToAction object (stored in the context) directly, breaking databinding.

3.) Finally you "un-do" this hard property setting by binding it to the context again. This has the effect you described.

Breaking the data binding principle for UI elements has an important drawback. It also breaks the generic Web Dynpro caching mechanisms. Read my article on

<a href="https://www.sdn.sap.comhttp://www.sdn.sap.comhttp://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/301d715e-0b01-0010-1a8b-f1f83d175972">Best Practices for Building Client-Independent Web Dynpro UIs</a>, section Coding Rules, rule <i>Implement Fine-Grain UI Manipulations on Context but Not on UI Element Level</i>:

To maximize the rendering performance of your Web Dynpro application, implement all fine-grain UI manipulations on context instead of UI element level. This means do not call the setter-methods of UI element objects inside wdDoModifyView()directly but bind the related properties to the context and call the corresponding setter methods outside wdDoModifyView():

<b>Not:</b> wdDoModifyView(){ … theField.setEnabled(true) … }

<b>But:</b> wdDoInit(){ … wdContext.currentFieldNode.setEnabled(true) … }.

Otherwise Web Dynpro’s caching mechanisms cannot speed up the rendering of view layouts.

The view controller’s wdDoModifyView() method is designed for a special purpose: the creation of a UI tree or UI sub-tree at runtime in case it is not possible to declare the UI at design time. The method is neither intended for fine-grain UI manipulations nor for context manipulations. Fine-grain UI manipulations are achieved via means of data binding. Context manipulations are done in wdDoInit(), action event handlers or event handlers.

Unfortunately, the name wdDoModifyView() is somewhat misleading since the purpose of it is to create (and not to modify) a UI tree dynamically. While the usage of wdDoModifyView() in order to create a UI tree initially (firstTime == true) is not performance critical, modifying an existing UI tree (firstTime == false) is: Changing only one single attribute of a single UI element within wdDoModifyView() flags the complete view containing the control as dirty and the complete view must be completely re-rendered again – depending on the size and complexity of the view this can result in significant performance hits.

But in your case databinding cannot be applied, as index binding is not supported. The only databinding solution must use multiple/n nodes of cardinatliy 1..1 instead of 1 node of cardinality 1..n with no node elements. And this would require further coding for dynamic context node creation, copy logic based on value semantic.

Best Regards, Bertram