on 2023 May 24 1:46 PM
Hey,
I have a smart table in a UI5 Freestyle app (Version 1.71.55). For this, I am using a smart filter bar with a custom filter. This custom filter must always be passed in the initial request. Once I have loaded the data from the OData service with this filter, only client-side filtering should be applied (using the personalization dialog for features such as sorting, filtering, and grouping), unless something changes in the filter bar - this should trigger a new oData request.
As it stands now, the smart table always sends an initial request (operation mode = client) without any filters, which is not possible for performance reasons in my scenario.
Now the questions to all UI5 experts: Is there a way to manipulate the initial oData request when the operation mode is set to client and thus pass the filters? Is there a way to control through the binding from the "onBeforeRebindTable" event of the smart table whether an initial request is sent?
Thank you very much for the support!
Leon
Request clarification before answering.
Hey, I managed to find a possible solution - it involves using the custom parameters of the bindings, and it's a bit hacky. Unfortunately, I haven't found any other way than overriding a function of the OData model. Otherwise, we would have had to modify the OData service in ABAP to read the filters from the custom parameters.
Please feel free to provide feedback or suggestions for improvement. Thank you!
My controller:
sap.ui.define(
["./BaseController", ..., "sap/base/security/encodeURL"],
/**
* @param {typeof sap.ui.core.mvc.Controller} Controller
*/
function (Controller, ..., encodeURL) {
/**
* Event handler rebindTable of smart table.
* sets operationMode to client, countMode to none and uses custom parameters
* to send filters within the initial request
* @param {sap.ui.base} oEvent The Event object
*/
onBeforeRebindTable(oEvent) {
const mBindingParams = oEvent.getParameter("bindingParams");
const oWorkCenterSelect = this.getView().byId("workCenterSelect");
const sWorkCenter = oWorkCenterSelect.getSelectedKey();
// overwrite function createCustomParams() of oDataModel V2 due to it would remove the $filter request
// in custom parameters
this._overWriteCreateCustomParams();
// set operation mode always to client - only one initial request will be fired to load the worklist,
// after that all filter, sorting, grouping actions are performed by the client without any requests
mBindingParams.parameters.operationMode = sap.ui.model.odata.OperationMode.Client;
// set countMode to none, due to we are not using pagination and it has impact on perfomance
mBindingParams.parameters.countMode = "None";
// set filter for the initial oData request via custom params due to the standard filter parameters are not respected by smarttable!
mBindingParams.parameters.custom = { $filter: `Arbid eq '${sWorkCenter}'` };
// attach dataReceived event to always restore the original function of oDataModel
mBindingParams.events = {
dataReceived: () => {
// Restore the original function createCustomParams of oDataModel to make sure this has no side effects to other parts of the app
this._restoreCreateCustomParams();
},
};
// reset view settings
this._resetViewSettings();
},
/**
* Overwrites original function "createCustomParams" of oDataModel V2 to prevent it from
* deleting custom parameters beginning with "$"
*/
_overWriteCreateCustomParams() {
// store the original function as private attribute
this._createCustomParams = this.getModel().createCustomParams;
// overwrite original function to prevent it from deleting custom parameters beginning with "$"
this.getModel().createCustomParams = function (mParameters) {
var aCustomParams = [],
mCustomQueryOptions,
mSupportedParams = {
expand: true,
select: true,
};
for (var sName in mParameters) {
if (sName in mSupportedParams) {
aCustomParams.push("$" + sName + "=" + encodeURL(mParameters[sName]));
}
if (sName === "custom") {
mCustomQueryOptions = mParameters[sName];
for (sName in mCustomQueryOptions) {
if (typeof mCustomQueryOptions[sName] === "string") {
aCustomParams.push(sName + "=" + encodeURL(mCustomQueryOptions[sName]));
} else {
aCustomParams.push(sName);
}
}
}
}
return aCustomParams.join("&");
};
},
/**
* Restores original function "createCustomParams" of oDataModel V2
* from parameter fOriginalFunction or, if not supplied, from private attribute _createCustomParams
* @param {function} fOriginalFunction - The original "createCustomParamsFunction"
*/
_restoreCreateCustomParams(fOriginalFunction) {
if (this.fOriginalFunction) this.getModel().createCustomParams = fOriginalFunction;
if (this._createCustomParams) this.getModel().createCustomParams = this._createCustomParams;
},
});
}
);
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
> Otherwise, we would have had to modify the OData service in ABAP to read the filters from the custom parameters.
This might not look as nice but if that adaptation of the backend service is modification free, it would be the better choice. The proposal above modifies the v2.ODataModel and problems caused by that can hardly be solved by SAP.
You could also try to add a navigation property from the workcenter to whatever_is_getting_displayed_in_your_table. This navigation property should implicitly contain the filter you are now adding explicitly.
Hi Mathias, thank you so much for your response! I've had a night to think about it, and after careful consideration, I really like your idea of creating a navigation property. However, I'm still unsure how to achieve the desired flexibility with it. Perhaps I didn't explain my example thoroughly enough because I also have scenarios where I want to filter not only by workcenter but also by material number and other fields. As far as I know, navigation properties only allow navigation through the key.
Best regards, Leon
User | Count |
---|---|
75 | |
30 | |
9 | |
8 | |
7 | |
6 | |
6 | |
5 | |
5 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.