Javascript 通过控制器动态创建UI元素,并将它们绑定到模型中的特定属性
我一直在尝试根据JSONmodel中的特定对象(一个对象数组)向对话框中添加动态内容 我的模型具有以下结构,我将其设置为(虚拟数据): 注意:我有多个模型在此控制器视图中处于活动状态,每个模型都有自己的模型数据 因此,我已成功设置了模型数据,现在我可以通过以下方式访问它:Javascript 通过控制器动态创建UI元素,并将它们绑定到模型中的特定属性,javascript,data-binding,sapui5,sap-fiori,two-way-binding,Javascript,Data Binding,Sapui5,Sap Fiori,Two Way Binding,我一直在尝试根据JSONmodel中的特定对象(一个对象数组)向对话框中添加动态内容 我的模型具有以下结构,我将其设置为(虚拟数据): 注意:我有多个模型在此控制器视图中处于活动状态,每个模型都有自己的模型数据 因此,我已成功设置了模型数据,现在我可以通过以下方式访问它: var modelData= this.oView.getModel("myModel").oData; 我现在想要的是动态创建sap.m.Dialog并用多个sap.m.Input元素动态填充它,这些元素的值基于我的模型中
var modelData= this.oView.getModel("myModel").oData;
我现在想要的是动态创建sap.m.Dialog
并用多个sap.m.Input
元素动态填充它,这些元素的值基于我的模型中的单个对象:
var getDialogContent = function(modelData){
var arr = [];
var keys = Object.keys(modelData[0]); // property names. I hard-coded first obj for test.
// I want to use these properties and bind a new input on dialog for each property.
jQuery.each(keys, function(i, key) {
// 'myModel>/emp/0/'+key is a supposed full path to property...
// according to this link:
// https://sapui5.hana.ondemand.com/1.36.6/docs/guide/91f0ed206f4d1014b6dd926db0e91070.html
newInput.bindProperty("value", 'myModel>/emp/0/' + key); //key is col1 the first time
newInput.setProperty("description", key);
newInput.setProperty("type", sap.m.InputType.Number);
arr.push(newInput);
});
return arr;
};
我在对话框的content属性中调用getDialogContent()来设置其内容
现在,除了绑定newInput.bindProperty(“value”,'myModel>/emp/0/'+键)之外,一切都正常了代码>,显示的输入字段只是空的,没有显示绑定的迹象,同样newInput.getBindingContext(“myModel”)代码>返回未定义的
var dialog = new sap.m.Dialog({
title: 'Dynamic dialog: ',
type: 'Message',
content: getDialogContent(modelData),
buttons: new sap.m.Button({
text: 'Cancel',
press: function () {
dialog.close();
}
}),
afterClose: function() {
dialog.destroy();
}
});
有人知道这里出了什么问题吗?为什么我不能将我的属性绑定到输入元素?我基本上只想将动态输入字段的值绑定到JSON模型中对象数组中的任意对象。欢迎提出任何建议
编辑(解决方案):
在varkeys=Object.keys(modelData[0])上当我访问特定的对象表单JSONModel时,代码>行I将modelData[0]
替换为modelData[“emp”][0]
。现在它可以工作了。你呢?当我在我们的应用程序中删除该步骤时,结果与您描述的完全一样:字段为空,并且getBindingContext()
返回未定义的以可重用方式实现对话框的最佳方法之一是中描述的方法。为了检索在该视图上设置的模型,您必须将对话框作为依赖项添加到“父”视图
onDialogOpen: function () {
if (!this.oDialog) {
this.oDialog = new sap.m.Dialog({
title: 'Dynamic dialog: ',
type: 'Message',
content: getDialogContent(modelData),
buttons: new sap.m.Button({
text: 'Cancel',
press: function () {
this.oDialog.close();
}.bind(this)
}),
afterClose: function() {
this.oDialog.destroy();
}.bind(this)
});
//to get access to the view models
this.getView().addDependent(this.oDialog);
}
this.oDialog.open();
},
嗨,约翰。你确定你说的是对话而不是片段吗?因为我还没有看到向视图的依赖项添加对话框的示例。但在你的链接中,让我感兴趣的是这样一句话:“对话框是特殊的,因为它们在常规应用程序内容之上打开,因此不属于特定的视图。”这是否意味着对话框无法访问视图的绑定上下文?我现在不能回答这个问题,因为我在家。。我明天上班时再回来看看。:)嘿,约翰,我把它弄到手了。我将这一行:var keys=Object.keys(modelData[0])改为:var keys=Object.keys(modelData[“emp”][0]),并像以前一样使用路径:newInput.bindProperty(“value”,“troskoviModel>/emp/0/”+key)昨天我尝试了一百万种变体,但我想我错过了这一种。起初,我在模型对象中直接添加数据,但没有“emp”标识符,因此无法工作。所以我添加了“'myModel>/emp/0/'+key”,这样我就可以像文档中建议的那样使用绝对路径。但我猜modelData[“emp”][0]是缺少的。感谢我从未向依赖项添加对话框的方式,我只是像其他任何输入元素一样动态创建了它。哦,天哪,我刚刚意识到“您是否将对话框添加到视图的依赖项中?”实际上是指这个。getView().addDependent(dialog)…嘿,我对此进行了一点修改,从我收集的信息来看,您的代码示例与我的不同之处在于.bind(this)
afterafterClose
事件属性。.bind(this)
实际上做什么?我在回复约翰的评论时解释说,不管怎样,我还是成功了。我还在输入字段上添加了一个更改事件:var newInput=new sap.m.input({change:this.onInputChanged})
,但我无法将任何参数传递给onInputChanged函数,因为当我在括号内添加一个参数时,this.onInputChanged(arg)
,会立即调用func。知道通过ARG的正确方法是什么吗?谢谢我的代码与您的代码不同,还因为我添加了两行基本代码(1)//以访问视图模型(2)this.getView().addDependent(this.oDialog);您要问的是一个基本的javascript问题。。。。这就是.bind()被发明的原因。我相信你可以用谷歌搜索它,找到大量关于它的信息。对不起,我刚刚意识到我没有发布所有的控制器代码。但是我已经添加了this.getView().addDependent(this.oDialog)
。我对此没有异议。还有,很抱歉这个愚蠢的问题,我一时疏忽,忘记了bind()是一个纯js:)我想问的是,您可能知道如何将自定义参数传递给newInput=new sap.m.Input({change:this.onInputChanged})
的更改事件吗?现在,我的onInputChanged func只接受作为触发事件的对象自动传递的参数。我也想传递“this”。没关系,我从你的书中拿出一页,在sap.m.Input({change:this.onInputChanged})中添加了.bind(this)到this.onInputChanged
。谢谢
onDialogOpen: function () {
if (!this.oDialog) {
this.oDialog = new sap.m.Dialog({
title: 'Dynamic dialog: ',
type: 'Message',
content: getDialogContent(modelData),
buttons: new sap.m.Button({
text: 'Cancel',
press: function () {
this.oDialog.close();
}.bind(this)
}),
afterClose: function() {
this.oDialog.destroy();
}.bind(this)
});
//to get access to the view models
this.getView().addDependent(this.oDialog);
}
this.oDialog.open();
},