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 创建一个包含一些逻辑的 DialogMainController 是打开对话框的 "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.jsonComponent.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();
            ...
        }
    });
});