Динамически создавайте UI5-Controls со свойствами из json -string. Проблемы с событиями в строке json - PullRequest
1 голос
/ 29 мая 2020

в своей реальной разработке я создаю приложение, которое должно динамически создавать UI5-Controls во время выполнения из таблицы настройки базы данных.

В качестве простого примера при создании поля ввода:

var loProObj = JSON.parse(pData.TEMPLATE);
var loInp = new sap.m.Input(loProObj);

Пока это работает для большинства свойств, когда pData.TEMPLATE - это JSON -String. Но это не работает для свойств метода событий. Затем я получаю сообщение об ошибке: Uncaught TypeError: I.fFunction.call не является функцией

Так упрощенно JSON -String для кода выше возьмите эту строку:

'{"value":"{boundVariable}","change":"onChange"}'

Когда эта строка анализируется (помните, что это строка, поступающая из базы данных для анализа на JSON, а не на JSON -Object), onChange все еще строка. это может быть проблемой. Но что я могу сделать, чтобы передать информацию о методах обработчика событий в json -строке?

Любые подсказки были бы отличными

С уважением, MatHay

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Как предлагается в комментарии , существуют API-интерфейсы publi c, с помощью которых можно создавать элементы управления из строковых значений.

Дано: определение пользовательского интерфейса в формате XML

Дано: view определение в формате JSON

То же, что XMLView.create, но вместо JSONView.create:

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/core/mvc/JSONView",
], JSONView => JSONView.create({
  definition: `{
    "Type":"sap.ui.core.mvc.JSONView",
    "content": [
      {
        "Type":"sap.m.Input",
        "width": "12rem",
        "placeholder": "Edit me",
        "change": "alert('Sample global handler triggered')"
      }
    ]
  }`,
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap"
  src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core, sap.m"
  data-sap-ui-async="true"
  data-sap-ui-theme="sap_fiori_3"
  data-sap-ui-compatversion="edge"
  data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>

Do c: JSON Просмотр


К сожалению, заводская функция для создание единого элемента управления из текста JSON (в настоящее время поддерживаются только XML, JS и HTML). Но если это действительно необходимо, вот моя попытка:

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/m/Input",
  "sap/ui/model/json/JSONModel",
], (Input, JSONModel) => {
  "use strict";
  
  const myController = {
    onInit: function() {
      createControlViaJSON({
        definition: `{
          "placeholder": "{/myPlaceHolder}",
          "change": "onInputChange",
          "width": "12rem"
        }`,
        TargetControl: Input,
        controller: this,
      }).setModel(new JSONModel({ myPlaceHolder: "Edit me" }))
        .addStyleClass("sapUiTinyMargin")
        .placeAt("content");
    },
    onInputChange: function(event) {
      alert(`You typed: ${event.getParameter("value")}`);
    },
  };
  
  // Emulating controller initialization:
  myController.onInit();
  
  // Could be a separate module:
  function createControlViaJSON({ id, definition, TargetControl, controller }) {
    // Very primitive sample! Ignoring aggregations, associations, etc..
    const control = new TargetControl(id);
    JSON.parse(definition, (key, value) => {
      if (typeof controller[value] == "function") {
        control.applySettings({
          [key]: [controller[value], controller],
        });
      } else if (key) {
        control.applySettings({
          [key]: value,
        });
      }
    });
    return control;
  }

}));
<script id="sap-ui-bootstrap"
  src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core, sap.m"
  data-sap-ui-async="true"
  data-sap-ui-theme="sap_fiori_3"
  data-sap-ui-compatversion="edge"
  data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>
1 голос
/ 29 мая 2020

loProObj.change = this[loProObj.change]

Преобразует строку "onChange" (или любое другое имя события) в фактическую функцию (если она доступна в контексте this). Затем эту функцию можно вызвать при срабатывании события.

Если вам нужен доступ к this в обработчике событий, я предлагаю:

loProObj.change = this[loProObj.change].bind(this)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...