I have a custom datatype derived from sap.ui.model.SimpleType, which does some unit converting and number formatting. When I create an instance of the data type, it represents a physical power with a particular unit (W, kW, MW, ...) and I would like to specify that unit inside the constructor. If I work with JS Views, this is not a problem, because I can simply add an additional parameter to the constructor. But I don't know how to specify this parameter within a XML view. Right now I abuse the formatOptions from sap.ui.base.ManagedObject.PropertyBindingInfo and just pass the unit as an additional property. However, I'm afraid that this is not really best practice and also not optimal, since I am passing the formatOptions to NumberFormat.getFloatinstance(...).
Is there a way to implement my intention more elegantly? I am grateful for any advice!
Datatype definition:
sap.ui.define([
"sap/ui/model/SimpleType",
"sap/ui/core/format/NumberFormat"
], function (SimpleType, NumberFormat) {
"use strict";
return SimpleType.extend("myNamespace.model.type.Power", {
aUnits : Object.freeze({
"SI" : 1.0,
"mW" : 0.001,
"W" : 1.0,
"kW" : 1000.0,
"MW" : 1000000.0
}),
constructor: function(oFormatOptions, oConstraints) {
let oDefaultFormatOptions = {
decimals : 0,
emptyString : null,
unit : "SI"
};
oFormatOptions = Object.assign(oDefaultFormatOptions, oFormatOptions);
SimpleType.apply(this, [oFormatOptions, oConstraints]);
this.oNumberFormat = NumberFormat.getFloatInstance(oFormatOptions);
},
formatValue: function(oValue) {
if(oValue !== undefined) {
if(this.oFormatOptions.unit !== "SI") {
oValue = this.convertValue(oValue, "SI", this.oFormatOptions.unit);
}
oValue = this.oNumberFormat.format(oValue);
}
return oValue;
},
parseValue: function(oValue) {
oValue = this.oNumberFormat.parse(oValue);
if(this.oFormatOptions.unit !== "SI") {
oValue = this.convertValue(oValue, this.oFormatOptions.unit, "SI");
}
return oValue;
},
validateValue: function(oValue) {
return oValue;
},
convertValue: function(oValue, sSourceUnit, sTargetUnit) {
if(!this.aUnits[sSourceUnit]) {
throw new Error("The source unit \"" + sSourceUnit + "\" is not valid or not yet implemented!" )
}
if(!this.aUnits[sTargetUnit]) {
throw new Error("The target unit \"" + sTargetUnit + "\" is not valid or not yet implemented!" )
}
if(oValue) {
oValue = oValue * this.aUnits[sSourceUnit] / this.aUnits[sTargetUnit];
}
return oValue;
}
});
XML View:
<mvc:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
controllerName="myNamespace.controller.MainView"
core:require="{Power : 'myNamespace/model/type/Power'}">
<Input id="InputA" value="{
path : 'model>powerA',
type : 'Power',
formatOptions : {
decimals : 0,
emptyString : null,
unit : "kW"
}}" />
</mvc:View>