问题描述
如果满足某些要求,我想将第二个视图嵌套到我的根视图中。通过创建XMLView对象并将其添加到<page>
元素的<App>
聚合中,可以很好地工作。但是,当我尝试通过manifest.json
访问默认模型(由this.getownerComponent().getModel()
文件创建)时,它会抛出:
未捕获的TypeError:无法读取未定义的属性'getModel'
它在根控制器中有效,但在嵌套控制器中,this.getownerComponent()
再次返回了undefined
。
即使在根视图的开头添加视图,它也可以工作。也许我在控制器中添加了错误的视图方式?
RootView.view.xml:
<mvc:View controllerName="test.demo.controller.RootView" xmlns:mvc="sap.ui.core.mvc">
<App id="app" xmlns="sap.m">
<Page id="page" title="{i18n>title}">
<Button text="load nested view" press=".onLoadButtonPress"/>
</Page>
</App>
</mvc:View>
RootView.controller.js:
sap.ui.define([
"sap/ui/core/mvc/Controller","sap/ui/core/mvc/XMLView"
],function (Controller,XMLView) {
"use strict";
return Controller.extend("test.demo.controller.RootView",{
onLoadButtonPress: function () {
this.mDefault = this.getownerComponent().getModel(); // works just fine
alert(this.mDefault);
XMLView.create({
viewName: "test.demo.view.nestedView"
}).then(function(oView) {
this.byId("page").addContent(oView);
}.bind(this));
}
});
});
nestedView.view.xml:
<mvc:View xmlns:mvc="sap.ui.core.mvc" controllerName="test.demo.controller.nestedView">
<!-- ... -->
</mvc:View>
nestedView.controller.js:
sap.ui.define([
"sap/ui/core/mvc/Controller"
],function (Controller) {
"use strict";
return Controller.extend("test.demo.controller.nestedView",{
onInit: function () {
this.mDefault = this.getownerComponent().getModel(); // throws Uncaught TypeError: this.getownerComponent() is undefined
alert(this.mDefault);
}
});
});
在manifest.json
中,我添加了GWSAMPLE_BASIC
OData服务作为默认模型。
解决方法
在JS上下文中创建视图(或任何其他元素)时,应在sap.ui.core.Component
中的方法runAsOwner
中进行。例如:
onLoadButtonPress: async function() {
const fn = () => XMLView.create({ viewName: "test.demo.view.NestedView" });
const oView = await this.getOwnerComponent().runAsOwner(fn);
this.byId("page").addContent(oView);
},
发件人:https://embed.plnkr.co/29UrnDHpTHquNWuH?show=controller/Nested.controller.js,preview
根据API参考:
对象的所有权仅在创建对象时由框架检查。此后不进行检查或更新。并且只能在执行
Component.runAsOwner
函数的过程中检测到它。如果不采取进一步措施,则只有在构造UIComponent的内容或路由器创建新的View和它的内容。 (source)
然后在嵌套视图的控制器中,调用this.getOwnerComponent()
应该返回组件而不是undefined
,因此调用this.getOwnerComponent().getModel()
也应该起作用。