В моем MainController я хотел бы вызвать функцию из моего ManualUploadController, нажав кнопку
Сам вызов функции работает нормально вот так:
var oManualUploadController = new ManualUpload();
var backendData = oManualUploadController.onGenerateBackendData();
Однако в методе onGenerateBackendData() я получаю модели, например, такие:
var oModel = this.getView().getModel('odataDetails');
Что смешно:
ManualUploadController создает Dialog с некоторой логикой, а MainController является «главной страницей», с которой открывается диалог.
При первоначальном доступе к главной странице и попытке нажать / выполнить эту функцию я получаю сообщение об ошибке
"Uncaught TypeError: Cannot read property 'getModel' of undefined".
Но когда диалоговое окно уже было открыто, затем снова закрыто, а затем нажимается кнопка на главной странице, вызов функции работает нормально без каких-либо ошибок.
Нужно ли мне каким-то образом создавать экземпляр контроллера или как я могу решить эту проблему?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если у вас есть MainController и ManualUploadController, я бы предложил поместить функцию в MainController, если вы хотите вызвать ее в обоих контроллерах.
Если вы используете библиотеки, попробуйте сначала создать экземпляр.
Но ваша проблема немного сложна.
Если вы хотите получить модель, вы можете попробовать получить ее через компонент.
Если вы хотите решить проблему отсутствия просмотра, вы можете попробовать
var backendData = oManualUploadController.onGenerateBackendData().bind(this)
Пробуя различные предложения @Blangero, я в конце концов нашел решение, которое сработало. (способ ".bind (this)", к сожалению, не работает. Это было бы самое простое решение)
Итак, вот что я сделал:
Я определил manualDialogView вне какой-либо функции моего контроллера:
sap.ui.define([
'workspace/controller/ManualUpload.controller',
],
function(ManualUpload) {
var oManualUploadController = new ManualUpload();
var manualDialogView = sap.ui.view({
viewName: "workspace.view.ManualDialog",
controller: oManualUploadController,
type: sap.ui.core.mvc.ViewType.XML
});
return BaseController.extend('workspace.controller.MainHeader', {
...
// rest of controller
...
}
Затем я создал экземпляр основного представления в onInit () и добавил manualDialogView в качестве зависимого:
onInit : function() {
var view = this.getView();
view.addDependent(manualDialogView);
},
Наконец, открытие моего manualDialogView находится в отдельной функции, и вызов функции, который я хотел бы получить от другого контроллера, отлично работает в другой функции:
onOpenManualDialog: function(oEvent) {
var dialog = manualDialogView.byId("manualUploadDialog");
manualDialogView.callbackAPI = this.callbackAPI;
dialog.open();
},
onExportBackendTable: function() {
var backendData = oManualUploadController.onGenerateBackendData();
... not relevant code
},
Если у вас есть код, который вы хотите использовать в нескольких контроллерах, я бы предложил поместить эту логику в новый файл / класс. Передайте компонент приложения конструктору, потому что он имеет доступ ко всем моделям, определенным в manifest.json и Component.js.
webapp / util / UploadHelper.js:
sap.ui.define([
"sap/ui/base/Object"
], function (BaseObject) {
"use strict";
return BaseObject.extend("workspace.util.UploadHelper", {
/**
* @param {sap.ui.core.UIComponent} oComponent reference to the app's component
*/
constructor: function (oComponent) {
this._oComponent = oComponent;
this._oResourceBundle = oComponent.getModel("i18n").getResourceBundle();
this._oModel = oComponent.getModel("odataDetails");
},
generateBackendData: function () {
// you can access this._oModel here and do stuff
return stuff;
}
});
});
Затем в вашем контроллере вы можете сделать
webapp / контроллер / MainHeader.controller.js
sap.ui.define([
"workspace/controller/BaseController",
"workspace/util/UploadHelper"
],
function(BaseController, UploadHelper) {
"use strict";
return BaseController.extend('workspace.controller.MainHeader', {
onInit: function() {
// pass your component.js to the constructor
var oComponent = this.getOwnerComponent();
this._oUploadHelper = new UploadHelper(oComponent);
...
},
onExportBackendTable: function() {
var oBackendData = this._oUploadHelper.generateBackendData();
...
}
});
});
Попробуйте поместить метод getModel () после открытия диалогового окна. В первый раз диалог не открывался. Итак, this.getView () возвращает undefined.