Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Karol-K
Advisor
Advisor

I just want to bring two examples for binding ZTL events to BIAL script, listed in the blog from Reiner:

What's Coming in Design Studio 1.4 SDK

and discussed in the threads:

DS 1.4 SDK: binding events to DS script

Design Studio 1.4 SDK - What is the correct approach for binding events to script methods for UI5-ba...

The examples are commited in the community repository in prototypes area, under:

The example is based on the question from Mustafa, how to automatically place the title from application name.

Basics

The events are send to the server, but not directly at the place where the call is located - and by this, you cannot expect that the next line in Java Script is already processed with the new values. The normal process sequence is still applied, the init method in the component and the update method in the component will be executed, then - if the event is directly placed in the update method - the event will be send to the server and again the update method will be executed. This can basically lead to endless loop, if the called method in ZTL will always change the component properties. if not, the loop will be broken by the current implementation of delta handling in design studio SDK.

The automatic bound events to private methods are positioned for user interaction of the component which does not require special code done by the developer (as the code is not dependent on other components in the application). For pushing some information to the component the implicit event "onBeforeRender" should be used.

Example 1.

Use of the onBeforeRender event linked to a method.

extension of contribution.xml:


<property
  id="onBeforeRender"
  title="Set Application Name"
  type="ScriptText"
    visible="false"/>
<property
  id="appName"
  title="Application Name"
  type="String"
  visible="false"/>
and...
<defaultValue property="onBeforeRender">this.private_beforeRender();</defaultValue>


extension of contribution.ztl:


// @Visibility(private)
  void private_beforeRender() {*
    // APPLICATION.createInfoMessage("Name: " + APPLICATION.getInfo().name);
      this.appName = "OnBeforeRender: " + APPLICATION.getInfo().name;
  *}


extension in java script file:


  afterDesignStudioUpdate: function() {
    // Set the logo text to the appName property filled by the onSetAppName event script
    this.setLogoText(this.getAppName());
  }


Example 2.

Use of implicit event which is triggered after initial rendering of the component.

extension of contribution.xml:


  <property
    id="onSetAppName"
    title="Set Application Name"
    type="ScriptText"
    visible="false"/>
  <property
    id="appName"
    title="Application Name"
    type="String"
    visible="false"/>
and...
<defaultValue property="onSetAppName">this.private_setAppInfoName();</defaultValue>


extension of contribution.ztl:


/* Sets the value of the invisible property appName to the application name */
  // @Visibility(private)
  void private_setAppInfoName() {*
  // APPLICATION.createInfoMessage("Name: " + APPLICATION.getInfo().name);
     this.appName = "Event: " + APPLICATION.getInfo().name;
  *}


extension in java script file:


afterDesignStudioUpdate: function() {
  // Set the logo text to the appName property filled by the onSetAppName event script
  this.setLogoText(this.getAppName());
  // Raise the onSetAppName event to execute the script for getting the application name
  this.fireDesignStudioEvent("onSetAppName");
}


Pros & Cons.

For this use case - fill in some information automatically on first rendering, example 1 is better, because:

  • it is triggered on the server "before render"
  • does not require additional roundtrip

Example 2 is positioned to an user action event which does not need to be coded by the application designer, therefore for this scenario it is not the best way, because:

  • it triggers additional request after first rendering which causes second rendering of the component.

Question 1

is there a difference in the sequence of the calls like below?


  // Set the logo text to the appName property filled by the onSetAppName event script
  this.setLogoText(this.getAppName());
  // Raise the onSetAppName event to execute the script for getting the application name
  this.fireDesignStudioEvent("onSetAppName");

VS.


  // Raise the onSetAppName event to execute the script for getting the application name
  this.fireDesignStudioEvent("onSetAppName");
  // Set the logo text to the appName property filled by the onSetAppName event script
  this.setLogoText(this.getAppName());

     Answer:

          No, there is no difference.

     Reason:

          The fireDesignStudioEvent call is NOT executing immediately, as there is no option to come back into the next line. The event is collected and executed after all component rendering is processed. Then, the normal dispatching is taking place - and leads again to the call into the function afterDesignStudioUpdate. Of course, this leads again to the trigger of the event - and in case the specific event implementation will return different value, there will be an endless loop. In case of the same value, the loop is stopped by the delta handling of SDK components (same values will be not send again..)

Question 2

why the events are not executed in design time?

     Answer:

          Designer is WYSIWYG, but not 100% - the onStartup scripts will be not executed as well. And looks like the events are also removed from the execution. The WYSIWYG is more linked to the layout and data display, but the initial interactivity is not included.

     Reason:

          The initial eventing in designer would lead to huge complexity, as the events can change the properties of the components - and then it would be a question which are now valid during the editing of the template - those saved in template or those set by the scripts.

Learning

  • the triggering of implicit events cannot be made in "initDesignStudio" method, those can be made ideally on user action, but implicitly also in "afterDesignStudioUpdate"
  • there is a bug in DS 1.4 SP0 (correction will be delivered in SP1) and the marker "@Visibility(private)" is not working at all (the method is not visible)
  • example 2 with the event would cause an endless loop, which is not occurring only because in this case the value is not changing and DS 1.4 supports delta rendering (is checking if the values have changed)

Code Example

Application

you just need to create new application and drag&drop one of the components.

Have fun with this examples.

9 Comments