Create a UI5-Controller on the Fly

482 Views Asked by At

Is it possible to create a sap.ui.controller like that:

sap.ui.controller("controllerId", "{onAfterRendering: function(){}}");

Use-Case is, i have a server that creates a controller on the fly, if needed.

When I get the Logic as String and try to use it like that:

var oView = sap.ui.view({
    type: sap.ui.core.mvc.ViewType.JSON,
    viewContent: viewContent,
    controller: sap.ui.controller("controllerId", "{onAfterRendering: function(){}}")
});

the Controller is always undefined.

Any hint on that topic?

EDIT 2:

After Timothy Groote updated answer:
Yes, i send a AJAX-Call to the Server. I have tried that right now:

var ajaxAnswer = 'sap.ui.controller("testForm", {  oView: null,  onAfterRendering: function(oEvent){oView = oEvent.getSource();}  });'

eval('var controller =' + ajaxAnswer);

But controller is undefined.

EDIT:

According to the Answer, i think i need to make it even clearer:

This part "{onAfterRendering: function(){}}" comes from the Server as a String. I can't remove any quotes from that String. I could parse it with JSON.parse(), but that can't parse a function.

2

There are 2 best solutions below

0
On BEST ANSWER

After I reported an Issue on github/SAP/openui5, they showed the right way to implement a sap.ui.controller. This is a JSBin Example
You should just eval() the ajax answer:

var ajaxAnswer = '{  oView: null,  onAfterRendering: function(oEvent){oView = oEvent.getSource();}  });';

eval('sap.ui.controller("testForm", ' + ajaxAnswer + ');');

and then let the View instantiate the controller:

var oViewDialog = sap.ui.view({
            type: sap.ui.core.mvc.ViewType.JSON,
            viewContent: JSON.stringify(oTreeTableModel.getData()),
            controller: sap.ui.controller("testForm")
        });

Due to the Documentation sap.ui.controller returns void or sap.ui.core.mvc.Controller, depending on the use case.

sap.ui.controller is always instantiated by a View with the controller name. If you create a sap.ui.controller("<Insert Name Here>", code Implementation)
you can instantiate it in your View with sap.ui.controller("<Insert Same Name As Above>").

0
On

According to the documentation provided with your framework ...

the constructor for a controller epects a string and an object literal as parameters.

since the string you're trying to add contains what looks like an object literal, all you need to do is remove the quotes around it.

like this:

var oView = sap.ui.view({
    type: sap.ui.core.mvc.ViewType.JSON,
    viewContent: viewContent,
    controller: sap.ui.controller("controllerId", {onAfterRendering: function(){}})
});

if for some reason the logic that is passed to you is always a string (because it was returned by an ajax call or for whatever reason) you simply need to parse the json string to an object first.

Most browsers support JSON.parse(json); for this purpose,

But will throw a fit if we pass it your example, since it won't parse functions. to do that, we simply need to tell it how to parse functions :

function parseJsonWithFunctions(jsonText)
{
   return JSON.parse(jsonText, function (key, value) 
   {
      if (value && (typeof value === 'string') && value.indexOf("function") === 0)    {
         // i know eval() is evil, so be careful please.
         eval("var jsFunc = " + value);
         return jsFunc;
      }

      return value;
  });
}

We can now do this :

var oView = sap.ui.view({
    type: sap.ui.core.mvc.ViewType.JSON,
    viewContent: viewContent,
    controller: sap.ui.controller("controllerId", parseJsonWithFunctions("{onAfterRendering: function(){}}")
});