SAPUI5:来自其他控制器的函数调用 - 如何实例化控制器或 this.getView()?
SAPUI5: Function call from other controller - how to instantiate controller or this.getView()?
在我的 MainController
中,我想通过按下按钮从我的 ManualUploadController
中调用一个函数
函数调用本身工作正常,如下所示:
var oManualUploadController = new ManualUpload();
var backendData = oManualUploadController.onGenerateBackendData();
但是,在 onGenerateBackendData()
方法中,我检索模型是这样的:
var oModel = this.getView().getModel('odataDetails');
搞笑的是:
ManualUploadController
创建一个包含一些逻辑的 Dialog
,MainController
是打开对话框的 "mainpage"。
最初访问主页并尝试 push/execute 该功能时,出现错误
"Uncaught TypeError: Cannot read property 'getModel' of undefined".
但是当对话框之前已经打开,然后再次关闭,然后主页上的按钮被按下时,函数调用工作正常,没有任何错误。
我是否必须以某种方式实例化控制器,或者我该如何解决这个问题?
如果您拥有 MainController 和 ManualUploadController,如果您想在两个控制器中调用它,我建议将函数放在 MainController 中。
如果您使用的是库,请先尝试实例化。
但是你的问题有点复杂
如果想获取model,可以尝试通过Component获取。
如果想解决获取视图失败的问题,可以试试
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
},
如果您有要在多个控制器中使用的代码,我建议将该逻辑放在新的 file/class 中。将 app 组件传递给构造函数,因为它可以访问 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/controller/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();
...
}
});
});
在我的 MainController
中,我想通过按下按钮从我的 ManualUploadController
中调用一个函数
函数调用本身工作正常,如下所示:
var oManualUploadController = new ManualUpload();
var backendData = oManualUploadController.onGenerateBackendData();
但是,在 onGenerateBackendData()
方法中,我检索模型是这样的:
var oModel = this.getView().getModel('odataDetails');
搞笑的是:
ManualUploadController
创建一个包含一些逻辑的 Dialog
,MainController
是打开对话框的 "mainpage"。
最初访问主页并尝试 push/execute 该功能时,出现错误
"Uncaught TypeError: Cannot read property 'getModel' of undefined".
但是当对话框之前已经打开,然后再次关闭,然后主页上的按钮被按下时,函数调用工作正常,没有任何错误。
我是否必须以某种方式实例化控制器,或者我该如何解决这个问题?
如果您拥有 MainController 和 ManualUploadController,如果您想在两个控制器中调用它,我建议将函数放在 MainController 中。
如果您使用的是库,请先尝试实例化。
但是你的问题有点复杂
如果想获取model,可以尝试通过Component获取。
如果想解决获取视图失败的问题,可以试试
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
},
如果您有要在多个控制器中使用的代码,我建议将该逻辑放在新的 file/class 中。将 app 组件传递给构造函数,因为它可以访问 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/controller/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();
...
}
});
});