Reputation: 1051
I have a question about custom controls in UI5. Say I want to use a formatter function in the custom control (see the snippet below). A colleague of mine insists that custom control should be as generic as possible (e.g. to be able to specify texts with commas, spaces and newlines in whichever way you need it to be). Thus my idea was to pass formatter function to the custom control. Is it possible and if yes how to do it?
sap.ui.define([
"pr/formatter/Formatter",
"sap/m/Popover",
"sap/m/Text"
], function(Formatter, Popover, Text) {
"use strict";
return Text.extend("pr.control.TextWithPopover", {
metadata: {
aggregations: {
_popover: {
type: "sap.m.Popover",
multiple: false,
visibility: "hidden"
}
}
},
init: function() {
const popover = new Popover({});
this.setAggregation("_popover", popover);
},
setText: function(text) {
if (this.getProperty("text") !== text) {
// How to make it generic?
const formattedText = Formatter.formatCommaListToNewLine(text);
const contentToAdd = new Text({ text: formattedText });
contentToAdd.addStyleClass("popoverContent");
// ...
}
},
renderer: "sap.m.TextRenderer",
});
});
Upvotes: 1
Views: 833
Reputation: 18054
UI5 introduced the standard type "function"
to sap/ui/base/DataType
in 1.46(Commit) which allows ManagedObject properties to receive functions as their values.
return ControlToExtend.extend("MyControl", {
metadata: {
properties: {
/**
* This function will contain foo and bar as parameters.
* Applications should return xyz.
*/
doSomethingWith: {
type: "function",
},
},
},
// ...
getXYZ: function(/*...*/) {
const doSomethingWith = this.getDoSomethingWith(); // function from the application
if (typeof doSomethingWith == "function") {
const [foo, bar] = [/*...*/];
return doSomethingWith(foo, bar);
} else {
/*default behavior*/;
}
},
});
<MyControl doSomethingWith=".myControllerMethod" /> <!-- or -->
<MyControl doSomethingWith="some.globally.available.function" /> <!-- or -->
<!-- Since 1.69: -->
<MyControl
xmlns:core="sap.ui.core"
core:require="{
'myRequiredFunction': 'mynamespace/myApplicationFunction'
}"
doSomethingWith="myRequiredFunction"
/>
Note: XMLTemplateProcessor
(XML-view / -fragment) supports function properties only as of 1.56. (Commit)
myApplicationFunction: function(foo, bar) {
// create and return xyz however the application wants;
},
This way, the control has no hard dependency to the application while keeping the flexibility to allow changing the default output or behavior.
The above option is one of the many solutions to reduce tight couplings in UI5. Another solution would be to add a control property which can be then manipulated by applications via binding and formatter.
Generally, controls (or control libraries) and control consumers (e.g. applications) should be always developed independently; with an interface in between (e.g. MenagedObjectMetadata
) and the controls being still open for extensions without disclosing how they're implemented internally.
Upvotes: 3