How to pass custom parameters for a binding datatype inside a xml view?

Viewed 286

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>
0 Answers
Related