使用 json-string 中的属性动态创建 UI5-Controls。 json-string 中的事件问题
Dynamically create UI5-Controls with properties from json-string. Problems with events in json-string
在我的实际开发中,我创建了一个应用程序,它需要在运行时从数据库自定义动态创建 UI5-Controls-table。
作为创建输入字段时的简单示例:
var loProObj = JSON.parse(pData.TEMPLATE);
var loInp = new sap.m.Input(loProObj);
到目前为止,当 pData.TEMPLATE 是 JSON-String 时,这对大多数属性都有效。
但它不适用于 Event-Method Properties.Then 我收到如下错误:Uncaught TypeError: I.fFunction.call is not a function
所以作为简化的 JSON- 上面代码的字符串取这个字符串:
'{"value":"{boundVariable}","change":"onChange"}'
当这个字符串被解析时(记住它是一个来自数据库的字符串被解析为 JSON,而不是一个 JSON-Object),onChange 仍然是一个字符串。这可能是问题所在。但是我该怎么做才能在 json-string 中传输有关事件处理程序方法的信息?
任何提示都很好
亲切的问候
马海
loProObj.change = this[loProObj.change]
这会将字符串 "onChange"
(或任何其他事件名称)转换为实际函数(如果它在 this
上下文中可用)。然后可以在触发事件时调用此函数。
如果您需要在事件处理程序中访问 this
,我建议:
loProObj.change = this[loProObj.change].bind(this)
如 中所建议,有 public API 可用于从字符串值创建控件。
给定:UI XML 格式的定义
给定: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>
不幸的是,目前还没有从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>
在我的实际开发中,我创建了一个应用程序,它需要在运行时从数据库自定义动态创建 UI5-Controls-table。
作为创建输入字段时的简单示例:
var loProObj = JSON.parse(pData.TEMPLATE);
var loInp = new sap.m.Input(loProObj);
到目前为止,当 pData.TEMPLATE 是 JSON-String 时,这对大多数属性都有效。 但它不适用于 Event-Method Properties.Then 我收到如下错误:Uncaught TypeError: I.fFunction.call is not a function
所以作为简化的 JSON- 上面代码的字符串取这个字符串:
'{"value":"{boundVariable}","change":"onChange"}'
当这个字符串被解析时(记住它是一个来自数据库的字符串被解析为 JSON,而不是一个 JSON-Object),onChange 仍然是一个字符串。这可能是问题所在。但是我该怎么做才能在 json-string 中传输有关事件处理程序方法的信息?
任何提示都很好
亲切的问候 马海
loProObj.change = this[loProObj.change]
这会将字符串 "onChange"
(或任何其他事件名称)转换为实际函数(如果它在 this
上下文中可用)。然后可以在触发事件时调用此函数。
如果您需要在事件处理程序中访问 this
,我建议:
loProObj.change = this[loProObj.change].bind(this)
如
给定:UI XML 格式的定义
给定: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>
不幸的是,目前还没有从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>