【问题标题】:Dynamically create UI elements via Controller and bind them to a specific properties in Model通过 Controller 动态创建 UI 元素并将它们绑定到 Model 中的特定属性
【发布时间】:2020-01-29 15:24:05
【问题描述】:

我一直在尝试根据我的 JSONmodel 中的特定对象向我的对话框添加动态内容,这是一个对象数组。

我的模型有以下结构,我设置成这样(虚拟数据):

注意我在这个控制器的视图中有多个活动模型,每个模型都有自己的模型数据。

this.setData( emp: [
                    {
                        col1: "1.4",
                        col2: "2.0",
                        col3: "3.1"
                    },
                    {
                        col1: "4.1",
                        col2: "5.3",
                        col3: "6.5"
                    }
                ]);

所以我已经成功设置了模型数据,现在我可以通过以下方式访问它:

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/' + key); 之外,一切正常,显示的输入字段只是空的并且没有显示绑定的迹象,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 模型中对象数组中的任意对象。欢迎提出任何建议。

编辑(解决方案): 在 var keys = Object.keys(modelData[0]); 行上,当我访问 JSONModel 的特定对象时,我将 modelData[0] 替换为 modelData["emp"][0]。现在可以了。

【问题讨论】:

    标签: javascript data-binding sapui5 sap-fiori two-way-binding


    【解决方案1】:

    add the dialog to the dependents of your view了吗?当我在我们的应用程序中删除该步骤时,结果与您描述的完全一样:字段为空,getBindingContext() 返回undefined

    【讨论】:

    • 嗨,约翰。你确定你在谈论对话框,而不是片段?因为我还没有看到将 Dialog 添加到视图依赖项的示例。但是,在您的链接中让我感到有趣的是这句话:“对话框很特别,因为它们在常规应用程序内容之上打开,因此不属于特定视图。”这是否意味着对话框无法访问视图的绑定上下文?我现在无法回答这个问题,因为我在家。我明天上班再回来看看。 :)
    • 嘿,约翰,我开始工作了。我将这一行: 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] 是缺少的。谢谢
    • 顺便说一句,我从未向依赖项添加对话框,我只是像任何其他输入元素一样动态创建它。
    • 天哪,我刚刚意识到“您是否将对话框添加到您的视图的依赖项?”你实际上的意思是 this.getView().addDependent(dialog)...
    【解决方案2】:

    以可重用方式实现对话框的最佳方法之一是this link 中描述的方法。您必须将对话框添加为依赖于“父”视图才能检索该视图上设置的模型。

    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();
            },
    

    【讨论】:

    • 嘿,我正在对此进行一些修改,据我收集的信息,您的代码示例与我的代码示例仅在 .bind(this) 之后 afterClose 事件属性不同。 .bind(this) 实际上是做什么的?无论如何,我得到了它的工作,我在回复约翰的评论中解释了。我还在输入字段上添加了一个更改事件:var newInput = new sap.m.Input({ change: this.onInputChanged }) 但我无法将任何参数传递给 onInputChanged 函数,因为当我在括号内添加一个参数this.onInputChanged(arg) 时,会立即调用 func。知道传递参数的正确方法是什么?谢谢!
    • 我的代码与你的不同,因为我添加了这两个基本行 (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 函数只接受作为触发事件的对象自动传递的参数。我也想传递“this”。
    • 没关系,我从你的书中取出一页并在sap.m.Input({ change: this.onInputChanged }) 中将.bind(this) 添加到this.onInputChanged。谢谢
    猜你喜欢
    • 2017-09-06
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2011-10-08
    • 1970-01-01
    • 2012-02-05
    • 1970-01-01
    相关资源
    最近更新 更多