I need to set the property to DataSet during onInit, to change the visiblity of some controls in my View. I could solve this problem with setting the visibility dynamically in controller. But I want to use the expression binding and the visible property in the View to set visibilites.
I'm getting an error in the function OnStartSetVisibilites. self.getView().getBindingContext() returns UNDEFINED. Without the sPath, I can't use setProperty. And without setProperty, my View-Controls don't know the visible-value.
How to fix this?
View:
<uxap:ObjectPageSubSection visible="{= ${Responsible} === '1'}" id="leader">
</uxap:ObjectPageSubSection>
OnInit in View-Controller:
onInit: function () {
var startupParameters = this.getOwnerComponent().getComponentData().startupParameters;
var sWorkitem = startupParameters.TASK[0];
this.setModel(this.getOwnerComponent().getModel());
this.getModel().metadataLoaded().then(function () {
var sObjectPath = this.getModel().createKey("DataSet", {
Workitem: sWorkitem
});
this.getView().bindElement({
path: "/" + sObjectPath
});
}.bind(this));
var self = this;
var model = this.getOwnerComponent().getModel();
this.getModel().read("/CharSet", {
success: function (response) {
$.sap.Chars = response.results;
self.onStartSetVisibilities(model, self);
}
});
// self.getView().attachAfterRendering(function () {
// self.onStartSetVisibilities(model, self);
// });
}
OnStartSetVisibilities:
onStartSetVisibilities: function (model, self) {
var char = model.getProperty(„GeneralData/Char");
if (char !== "" || char !== null) {
model.setProperty(self.getView().getBindingContext().sPath + "/Responsible",
this.getResponsibleForChar(char));
}
}
I put together some code which might solve your issue (it's untested so it may contain syntax errors!).
I introduced the concept of Promises which simplifies the asynchronous behavior of JS. I also replaced some of the inner functions with Arrow functions so you don't have to deal with that
or self
. Arrow functions basically use the this
of the scope they are defined within.
Your app should now have a proper flow.
CharSet
.onInit: function () {
const startupParameters = this.getOwnerComponent().getComponentData().startupParameters;
const sWorkitem = startupParameters.TASK[0];
this._bindView(sWorkitem)
.then(() => this._readCharSet())
.then(() => this._setVisibilities())
},
_bindView: function (sWorkitem) {
return new Promise((resolve) => {
const oModel = this.getOwnerComponent().getModel();
oModel.metadataLoaded().then(() => {
const sPath = "/" + oModel.createKey("DataSet", {
Workitem: sWorkitem
});
this.getView().bindElement({
path: sPath,
events: {
change: resolve,
dataReceived: resolve
}
});
});
});
},
_readCharSet: function () {
return new Promise((resolve) => {
const oModel = this.getOwnerComponent().getModel();
oModel.read("/CharSet", {
success: resolve
});
});
},
_setVisibilities: function () {
const oModel = this.getOwnerComponent().getModel();
const sChar = oModel.getProperty("GeneralData/Char");
if (sChar) {
// ...
}
}