Reputation: 2594
I am working with Javascript and Appdescriptors in JSON format.
What I want to do is creating a instance of a Class, where the classname is saved as string in oModelConf[sModelName].type
. If that is not the case I want to take "sap.ui.model.odata.ODataModel"
Related Question offers this solution:
function instantiate(className, args) {
var o, f, c;
c = window[className]; // get reference to class constructor function
f = function(){}; // dummy function
f.prototype = c.prototype; // reference same prototype
o = new f(); // instantiate dummy function to copy prototype properties
c.apply(o, args); // call class constructor, supplying new object as context
o.constructor = c; // assign correct constructor (not f)
return o;
}
This is not a very good solution I think.
EDIT It does not work for me because my class is not defined on window, so window[className]
is undefined. I do not know where my function is defined in SAPUI5
A second Solution:
eval(`a = new ${oModelConf[sModelName].type || "sap.ui.model.odata.ODataModel"}(sServiceUrl, true);`);
This is not a better solution because we should not use eval()
.
Are there any better solutions?
EDIT2 Because of the url in pimskies answer I found an other solution:
Since window.sap.ui.model.odata.ODataModel
is the same as sap.ui.model.odata.ODataModel
and window.sap
is the same as window[sap]
I could take my string, and replace all .
with ][
, put the right brackets to front and end.
I will not code that because it is not a going solution.(I should not have coded the eval
thing too...)
Upvotes: 0
Views: 1141
Reputation: 3948
You could use jQuery.sap.getObject to access the class:
var ModelClass = jQuery.sap.getObject(oModelConf[sModelName].type || "sap.ui.model.odata.ODataModel");
var model = new ModelClass();
Edit: An other way (which i would recommend if you use AMD)
If you are using the modern AMD modules and you don't know if the module containing your class has already been loaded, you should use sap.ui.require() to load the module asynchronously. It requires the module to be specified via its unified resource name (the conversion is probably the most ugly part):
var className = oModelConf[sModelName].type || "sap.ui.model.odata.ODataModel";
var urn = className.replace(".", "/"); //Convert to unified resource name
sap.ui.require([urn],function(ModelClass){
//This function is called when the module is available
var model = new ModelClass();
...
});
Upvotes: 3
Reputation: 957
What not combine the two? Since window[className]
is failing, replace it with
oModelConf[className].type || sap.ui.model.odata.ODataModel
...
function instantiate(className, args) {
var o, f, c;
c = oModelConf[className] || sap.ui.model.odata.ODataModel;
f = function(){}; // dummy function
f.prototype = c.prototype; // reference same prototype
o = new f(); // instantiate dummy function to copy prototype properties
c.apply(o, args); // call class constructor, supplying new object as context
o.constructor = c; // assign correct constructor (not f)
return o;
}
Upvotes: 0
Reputation: 1871
Maybe map the string to a class?
function Foo() {
console.log('new foo');
}
function Bar() {
console.log('new bar');
}
var objects = {
'foo': Foo,
'bar': Bar
};
var cls = objects.foo || Bar;
new cls();
https://jsfiddle.net/ckd56d9v/1/
Or take a look at this answer: https://stackoverflow.com/a/9804142/5930258
Upvotes: 0