Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

sapui5 - Global Model Not Accesible

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?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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, descendants of ComponentContainer are unaware of such models by default as explained above.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...