通过json-string的属性动态创建UI5-Controls。json-string中事件的问题

问题描述 投票:0回答:1

在我的实际开发中,我创建了一个应用程序,它需要在运行时从数据库的自定义表中动态地创建UI5-控制。

作为一个简单的例子,当创建一个输入字段时。

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

当pData.TEMPLATE是一个JSON-String时,这对大多数属性都有效。但是对于Event-Method属性来说,它就不工作了。Uncaught TypeError.I.fFunction.call为JSON-Strate时,大多数属性都能正常工作。I.fFunction.call不是一个函数。

所以上面的代码简化为JSON-String,取这个字符串。

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

当这个字符串被解析时(记住它是一个从数据库来的字符串,将被解析为JSON,而不是JSON-Object),onChange仍然是一个字符串,这可能就是问题所在。但是,我可以做什么来传输关于偶件方法的信息在一个json-string中?

任何提示都将是巨大的

亲切地问候MatHay

sapui5
1个回答
1
投票

如同在本书中建议的那样 评论有一些公共API可以通过字符串值创建控件。

给定。XML格式的UI定义

给定: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>

Doc: JSON View


遗憾的是,目前还没有用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>

2
投票

loProObj.change = this[loProObj.change]

这个函数可以将字符串 "onChange" 或任何其他事件名称)到实际的函数中(如果它在 this context)。当事件被触发时,这个函数就可以被调用。

如果您需要访问 this 我建议在你的事件处理程序中。

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

© www.soinside.com 2019 - 2024. All rights reserved.