Reputation: 225
I declared a model in Component.js of a UI5 application as below
init: function() {
sap.ui.core.UIComponent.prototype.init.apply(this);
var oModel1 = new sap.ui.model.json.JSONModel("model/mock.json");
sap.ui.getCore().setModel(oModel1, "oModelForSales");
},
but was not able to access the model in any of the onInit
methods inside controllers unless the model is set on view instead as below:
var oModel1 = new sap.ui.model.json.JSONModel("model/routes.json");
this.getView().setModel(oModel1);
The log for sap.ui.getCore().getModel("oModelForSales")
in controllers onInit
shows the model as undefined
but I was able to fetch it in onBeforeRendering
handler.
Why are core models, set in Component.js, not accessible in onInit
?
Upvotes: 5
Views: 10363
Reputation: 18064
Avoid setting models on the Core directly if you're using Components. Components are meant to be independent and reusable parts and therefore will not inherit the Core models by default. Models should be set depending on your business case:
Models declared in the app descriptor (manifest.json
) section /sap.ui5/models
will be set on the Component. They are automatically propagated to its descendants. Given default model, the following returns true:
this.getOwnerComponent().getModel() === this.getView().getModel() // returns: true
Note: calling this.getView().getModel()
in onInit
will still return undefined
since the view doesn't know its parent at that moment yet (this.getView().getParent()
returns null
). Therefore, in onInit
, call the getModel
explicitly from the parent that owns the model. E.g.:
{ // My.controller.js
onInit: function {
// The view is instantiated but no parent is assigned yet.
// Models from the parent aren't accessible here.
// Accessing the model explicitly from the Component works:
const myGlobalModel = this.getOwnerComponent().getModel(/*modelName*/);
},
}
Set models only on certain controls (e.g. View, Panel, etc.) if the data are not needed elsewhere.
Set models on the Core only if the app is not Component-based.
If Core models or any other model from upper hierarchy should still be propagated to the Component and its children, enable propagateModel
when instantiating the ComponentContainer.
new ComponentContainer({ // required from "sap/ui/core/ComponentContainer"
//...,
propagateModel: true // Allow propagating parent binding and model information (e.g. from the Core) to the Component and it's children.
})
But again, this is not a good practice since Core models can be blindly overwritten by other apps on FLP as SAP recommends:
Do not use
sap.ui.getCore()
to register models.
About the Core model being undefined in onInit
: This is not the case anymore as of version 1.34.0. The Core model can be accessed from anywhere in the controller. However, child elements of ComponentContainer
are unaware of such models by default as explained above.
Upvotes: 19
Reputation: 1098
Adding more info on this:
During onInint
of a controller, the view/controllers do not know their parent as where would they land, and hence they can not refer to the model.
However, this can be achieved from the following code:
this.getOwnerComponent().getModel()
As the component is already initialized and should return the model.
Upvotes: 1
Reputation: 2353
can you once try this code -
init:function(){
//sap.ui.core.UIComponent.prototype.init.apply(this);
var oModel1 = new sap.ui.model.json.JSONModel("model/mock.json");
sap.ui.getCore().setModel(oModel1,"oModelForSales");
console.log(sap.ui.getCore().getModel("oModelForSales"));
sap.ui.core.UIComponent.prototype.init.apply(this);
},
and then in you init method of any controller try -
console.log(sap.ui.getCore().getModel("oModelForSales"));
I think sap.ui.core.UIComponent.prototype.init.apply(this);->calls the create content methods and your view and controllers are initialised even before your model is defined, hence you get undefined as model. Using my approach, we create the model first and then call the super init method in Component.
Note @Admins-> I dont have enough points to comment, so adding an answer.
Upvotes: -1
Reputation: 2412
You should not set the Model to the Core.
Instead set it to the Component. That way the Controllers and Views belonging to that Component will be able to access it.
Upvotes: 1