首页 > 解决方案 > 从另一个控制器调用函数后 SAPUI5 this.getView() 未定义

问题描述

我有TransformationConfiguration.controller.jsBaseRequest.js,我想在其中外包我的 fetch 后端请求,因为测试更容易。

问题是如果_getConfigList()是从 BaseRequest.js 中的deleteConfiguration函数调用this.getView ().setModel(oModelConfigList, "ConfigList"); 不起作用,因为 this.getView() 未定义。但是如果在 onInit中调用_getConfigList ()一切正常。

另一个问题是MessageToast.show(this.getView().getModel("i18n").getResourceBundle().getText("successfulDeleted")); 不起作用,因为这里的 this.getView() 也未定义。

有人可以给我一个解决方案吗,我试图解决这个问题几个小时。提前致谢!

TransformationConfiguration.controller.js:

sap.ui.define([
  "com/transformationConfigurationUI/controller/BaseController",
  "com/transformationConfigurationUI/controller/BaseRequests",
  //...

], function (Controller, BaseRequests, MessageBox, MessageToast, FilterOperator, Filter, JSONModel, formatter, Sorter, sorter, CoreLibrary) {
  "use strict";
  var ValueState = CoreLibrary.ValueState;
  return Controller.extend("com.transformationConfigurationUI.controller.TransformationConfiguration", {
    formatter: formatter,

    onInit: function () {
      this._getConfigList(); // <-- works fine!
      //...
    },

    _getConfigList: function () {
      var oModelConfigList = new JSONModel();
      this.request = new BaseRequests();
      this.request.getAllConfigurations()
        .then(json => {
          oModelConfigList.setData(json);
        });
      this.getView().setModel(oModelConfigList, "ConfigList"); // if called from onInit works fine
//if called from that.request.deleteConfiguration(selectedConfigUuid); this.getView() is undefined!
    },

//...


onDelete: function (oEvent) {
      //create selected Config
      this._createSelectedConfigModel(oEvent.getSource().getParent().getParent().getBindingContextPath());

      var oModelSelectedConfig = this.getView().getModel("SelectedConfig");
      var selectedConfigName = oModelSelectedConfig.getProperty("/name");
      var selectedConfigUuid = oModelSelectedConfig.getProperty("/uuid");
      var that = this;
      MessageBox.show(this.getView().getModel("i18n").getResourceBundle().getText("deleteConfiguration", [selectedConfigName]), {
        id: "deleteWarningDialog",
        title: this.getView().getModel("i18n").getResourceBundle().getText("delete"),
        icon: MessageBox.Icon.WARNING,
        actions: [MessageBox.Action.DELETE, MessageBox.Action.CANCEL],
        emphasizedAction: MessageBox.Action.DELETE,
        onClose: function (oAction) {
          if (oAction === MessageBox.Action.DELETE) {

            that.request.deleteConfiguration(selectedConfigUuid); //Problem here?
           
          } else {
            MessageToast.show(that.getView().getModel("i18n").getResourceBundle().getText("canceled"));
          }
        }
      });
    },


//...


_createSelectedConfigModel: function (configPath) {
      var oModelConfigList = this.getView().getModel("ConfigList");
      var oSelectedConfig = oModelConfigList.getProperty(configPath);
      var oSelectedConfigBrokenBinding = JSON.parse(JSON.stringify(oSelectedConfig));
      var oModelSelectedConfig = new JSONModel(oSelectedConfigBrokenBinding);
      this.getView().setModel(oModelSelectedConfig, "SelectedConfig");
    },

//...

  });
});

BaseRequest.js:

sap.ui.define([
  "sap/ui/base/ManagedObject",
  "sap/m/MessageToast"
], function (
  ManagedObject, MessageToast
) {
  "use strict";

  return ManagedObject.extend("com.transformationConfigurationUI.controller.BaseRequests", {

    getAllConfigurations: function () {
      return fetch("http://localhost:8080/transformations/ui/")
        .then(response => response.json());
    },

    deleteConfiguration: function (uuid) {
      fetch("http://localhost:8080/transformations/" + uuid, {
        method: "DELETE"
      }).then((response) => {
        if (response.ok) {
           MessageToast.show(this.getView().getModel("i18n").getResourceBundle().getText("successfulDeleted"));
          //this.getView() is undefined
          sap.ui.controller("com.transformationConfigurationUI.controller.TransformationConfiguration")._getConfigList(); //Problem here?
        } else {
           MessageToast.show(response.statusText);
        }
      });
    }
  });
});

标签: javascriptcontrollersapui5this

解决方案


对我来说,看起来你应该在使用它之前阅读更多关于委托模式的内容。

你在这里基本上有3个选择。

我假设第一个文件是一个控制器和来自sap.ui.base.Objector的委托sap/ui/base/ManagedObject。当心onInit vs constructor

  1. 在 new 期间传递一个控制器实例,因此你有一个控制器的 ref
    onInit: function () {
          this._requestor = new BaseRequests(this);
          
    },
    onThat: function () {
          this._requestor.getAllConfigurations()
    },
    // should be in _requestor, here just for readability 
    constructor: function (controller) {
          this._controller = controller;
          
    },
    getAllConfigurations: (callback) {
         this._controller.doSomething()
    },

  1. 不是很现代,但仍然是一种 js 方式。传递回调
    onInit: function () {
          this._requestor = new BaseRequests();      
    },
    onThat: function () {
         
         var doThatAfterwards = (result) =>{
           // this here points to the controller
          }
          this._requestor.getAllConfigurations(doThatAfterwards)
    },,
    // should be in _requestor, here just for readability 
    getAllConfigurations: (callback) {
         callback("myresult")
    },
  1. 使用 Promise 可以在任何地方创建 Promise,甚至可以帮助你处理同步/异步的东西
    onInit: function () {
          this._requestor = new BaseRequests();      
    },
    onThat: function () {
          this._requestor.getAllConfigurations.then((result) =>{
           // this here points to the controller
           // result contains 'foo'
          })
    },
    // should be in _requestor, here just for readability 
    getAllConfigurations: () {
         return new Promise((resolve, reject) => {
           setTimeout(() => { resolve('foo'); }, 300);
     });
    },


推荐阅读