Nikolai Kim
Nikolai Kim

Reputation: 705

Writing SAPUI5 control renderer in "sap.ui.define" style

I'd like to write custom control in a new sap.ui.define fashion. I have a problem implementing control renderer in a separate file: it seems one have to put bExport = true, while this is forbidden by SAP.

bExport: whether an export to global names is required - should be used by SAP-owned code only

I haven't found any examples of renderer implementations that doesn't utilize export hack and I have a doubt if such a way ever exists.

I've got some suggestions, but they doesn't fully satisfy me:

What is the best or recommended way to resolve this issue?


Technically, an object reference available for public use is created inside framework code with jQuery.sap.setObject method, both in:

  1. sap.ui.core.Control.extend() -- actually within parent class method sap.ui.base.Metadata.createClass()
  2. sap.ui.define(/* bExport = */ true)

This method creates hierarchy of objects in global scope by object dot.separated.qualified.name as follows:

jQuery.sap.setObject = function(sName, vValue, oContext) {
  var oObject = oContext || window,
      aNames = (sName || "").split("."),
      l = aNames.length,
      i;

  if (l > 0) {
    for (i = 0; oObject && i < l - 1; i++) {
      if (!oObject[aNames[i]]) {
        oObject[aNames[i]] = {};
      }
      oObject = oObject[aNames[i]];
    }
    oObject[aNames[l - 1]] = vValue;
  }
};

Upvotes: 3

Views: 1913

Answers (1)

schnoedel
schnoedel

Reputation: 3948

First, your Renderer is an Object with a render function. It's a static function. Return this Renderer from your module.

sap.ui.define([], function(){
  "use strict";
  var MyControlRenderer = {};
  MyControlRenderer.apiVersion = 2;
  MyControlRenderer.render = function(oRm, oControl){
    // Render your control
  };
  return MyControlRenderer;
});

Then in your control, you import your Renderer object and assign it to the renderer property of your control like this:

sap.ui.define([
  "sap/ui/core/Control",
  "./MyControlRenderer"
], function(Control, MyControlRenderer) {
  "use strict";
  var MyControl = Control.extend("bla.MyControl", {
    metadata: {
      // ...
    },
    renderer: MyControlRenderer
  });
  return MyControl;
});

In this example the renderer is in the same directory as the control.

Upvotes: 3

Related Questions