#sapui5
#sapui5
Вопрос:
Я хочу вложить второй вид в мой корневой вид, если будут выполнены некоторые требования. Это отлично работает путем создания объекта XMLView и добавления его в <page>
агрегацию <App>
элемента. Но когда я пытаюсь получить доступ к модели по умолчанию (которая создается manifest.json
файлом) через this.getOwnerComponent().getModel()
, он выдает:
Неперехваченная ошибка типа: не удается прочитать свойство ‘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 в качестве модели по умолчанию.
Ответ №1:
Когда вызывающий объект в коде приложения создает по требованию представление или любой другой экземпляр managedObject, из которого должна быть доступна информация о компоненте владельца, это должно быть сделано в методе runAsOwner
из вашей цели sap.ui.core.Component
. Например:
// XMLView required from "sap/ui/core/mvc/XMLView"
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
Согласно ссылке на API:
Владение объектами проверяется фреймворком только во время их создания. Впоследствии оно не проверяется и не обновляется. И это может быть обнаружено только во время выполнения
Component.runAsOwner
функции. Без дальнейших действий это имеет место только при создании содержимого UIComponent или когда маршрутизатор создает новое представление и его содержимое. (источник)
Затем в контроллере вложенного представления вызов this.getOwnerComponent()
возвращает правильно назначенный компонент вместо undefined
и, таким образом, this.getOwnerComponent().getModel()
работает.
Совет: при загрузке фрагментов отдавайте предпочтение API loadFragment
контроллера, Fragment.load
поскольку loadFragment
он автоматически вызывает Fragment.load
компонент контроллера .runAsOwner
.src