SAPUI5 this.getView() не определен после вызова функции с другого контроллера

#javascript #controller #sapui5 #this

Вопрос:

У меня есть TransformationConfiguration.controller.js и BaseRequest.js где я хочу передать свои запросы на извлечение на аутсорсинг из-за более простого тестирования.

Проблема в том, что _getConfigList() вызывается из функции deleteConfiguration в BaseRequest.js this.getView().setModel(oModelConfigList, «Список настроек»); не работает, так как this.getView() не определен. Но если _getConfigList() вызывается в OnInit, все работает нормально.

Другая проблема заключается в том, что MessageToast.show(this.getView().getModel(«i18n»).getResourceBundle().getText(«Успешно удалено»)); не работает, так как 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);
        }
      });
    }
  });
});
 

Комментарии:

1. Вы можете передать ссылку на ваш TransformationConfiguration.controller конструктору Baserequest и использовать эту ссылку для получения представления. Или вы можете привязать методы к своему контроллеру при их вызове, например that.request.deleteConfiguration.call(that, uuid) . Но это выглядит довольно странно, так как это уже переменная-член контроллера

2. @user1882585 Спасибо, ваш подход that.request.deleteConfiguration.call(that, uuid) сработал, но я не знаю, является ли это лучшим решением. До сих пор мне не удавалось передать ссылку на TransformationConfiguration.controller конструктору Baserequest и использовать эту ссылку для получения представления. У вас есть фрагмент кода?

Ответ №1:

для меня это выглядит так, как будто вам следует прочитать больше о шаблоне делегирования, прежде чем использовать его.

Здесь у вас есть в основном 3 варианта.

Я предполагаю, что первый файл-это контроллер и делегат от sap.ui.base.Object или sap/ui/base/ManagedObject . Следите за onInit vs constructor

  1. передайте экземпляр контроллера во время создания, следовательно, у вас есть ссылка на контроллер
     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. используйте обещания
    Обещания могут быть созданы везде и даже помогут вам с синхронизацией/асинхронностью
     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);
     });
    },

 

Комментарии:

1. Если я передам экземпляр контроллера во время создания с new BaseRequests(this); , я получу много неудачных утверждений. Например, managedObject.apply: обнаружена неизвестная настройка «mEventRegistry» для класса «com.transformationConfigurationUI.controller.BaseRequests» (значение: «[объект объекта]»)

2. видеть sapui5.hana.ondemand.com/#/topic/…

3. Вам нужно расширить managedObject для вашего обработчика? Может sap.ui.base.Object быть, это более уместно?

4. я предполагаю, что если вы передадите что-то без перезаписи конструктора. ты позвонишь старому. Я обновляю свой пример. OnInit-это жизненный цикл контроллера