从Controller的onInit方法访问全局模型

use*_*850 3 sapui5

我在UI5应用程序的Component.js中声明了一个模型,如下所示

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");
},
Run Code Online (Sandbox Code Playgroud)

但是无法onInit在控制器内部的任何方法中访问模型,除非在视图上设置模型,如下所示:

var oModel1 = new sap.ui.model.json.JSONModel("model/routes.json");
this.getView().setModel(oModel1);
Run Code Online (Sandbox Code Playgroud)

sap.ui.getCore().getModel("oModelForSales")控制器onInit中的日志显示模型为,undefined但我能够在onBeforeRendering处理程序中获取它.

为什么在Component.js中设置的核心模型无法访问onInit

Bog*_*ann 16

如果您正在使用组件,请避免直接在Core上设置模型.组件是独立的和可重用的部件,因此默认情况下不会继承Core模型.应根据您的业务案例设置模型:

  • 应用程序描述符(manifest.json)中定义的模型将在Component上设置.它们会自动传播到其后代.给定默认模型,以下返回true:

    this.getOwnerComponent().getModel() === this.getView().getModel() // returns: true
    
    Run Code Online (Sandbox Code Playgroud)

    注:调用this.getView().getModel(/*modelName*/)onInit 仍然返回undefined因为视图不知道其父在那一刻,但(this.getView().getParent()回报null).因此,在拥有该模型的父级中显式onInit调用getModel:

    onInit: function() {
      const model = this.getOwnerComponent().getModel(/*modelName*/);
      // instead of this.getView().getModel
    },
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果在其他地方不需要数据,则仅在某些控件(例如视图,面板等)上设置模型.

  • 仅当应用程序不是基于组件时才在Core上设置模型.

如果Core模型或上层次结构中的任何其他模型仍应传播到Component及其子项,则propagateModel在实例化ComponentContainer时启用.

new ComponentContainer({
    //...,
    propagateModel: true
})
Run Code Online (Sandbox Code Playgroud)

但同样,这不是一个好的做法,因为Core建模可以被FLP上的其他应用程序盲目覆盖,如SAP推荐:

千万不能使用sap.ui.getCore()注册模式.


关于未定义的核心模型onInit:从版本1.34.0开始不再是这种情况.可以从控制器中的任何位置访问Core模型.然而,ComponentContainer如上所述,默认情况下的后代默认不知道这些模型.


Rah*_*waj -1

你可以尝试一下这个代码吗 -

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);
    },
Run Code Online (Sandbox Code Playgroud)

然后在任何控制器的 init 方法中尝试 -

console.log(sap.ui.getCore().getModel("oModelForSales"));
Run Code Online (Sandbox Code Playgroud)

我认为 sap.ui.core.UIComponent.prototype.init.apply(this);-> 调用创建内容方法,并且您的视图和控制器甚至在定义模型之前就已初始化,因此您未定义为模型。使用我的方法,我们首先创建模型,然后调用 Component 中的 super init 方法。

注意@Admins->我没有足够的点来评论,所以添加一个答案。

  • 您不应该在核心中全局注册模型,因为它可能会被您无法控制的第三方代码覆盖 (2认同)