OpenUI5:将sap.m.ComboBox绑定到sap.ui.table.table中的JSONModel()列

OpenUI5:将sap.m.ComboBox绑定到sap.ui.table.table中的JSONModel()列,combobox,binding,sapui5,Combobox,Binding,Sapui5,我已经熟悉OpenUI5好几个星期了,我一直面临新的问题,比如我现在要问的问题。就像我一直做的那样,我正确地完成了我的家庭作业——寻找解决方案、文档、类似的线程等等 我想要实现的目标:我想要在sap.ui.table.table的一列中显示一个sap.m.ComboBox,并将其绑定到当前行的相应值。他们应该能够通过选择Change(更改)来更改特定行的值 到目前为止我的进展是什么:我使用的是标准的$.ajax();调用以填充如下模型: oModel = new sap.ui.model.jso

我已经熟悉OpenUI5好几个星期了,我一直面临新的问题,比如我现在要问的问题。就像我一直做的那样,我正确地完成了我的家庭作业——寻找解决方案、文档、类似的线程等等

我想要实现的目标:我想要在
sap.ui.table.table
的一列中显示一个
sap.m.ComboBox
,并将其绑定到当前行的相应值。他们应该能够通过选择Change(更改)来更改特定行的值

到目前为止我的进展是什么:我使用的是标准的$.ajax();调用以填充如下模型:

oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataToShow); // dataToShow being an array of entities
{
    itemID: '123',
    state: 1 // state is an int column in the database
}
oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "Number of item" }),
    template: new sap.ui.commons.TextView({ text: "{itemID}" }),
    sortProperty: "itemID", // https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/ui/table/demokit/Table.html#__2
    filterProperty: "itemID",
    width: gridTestColWidth
}));
// first, hard-code (for now) the list of possible items
var cbStateItems = [
    {
        Code: 0,
        //Code: '0', // I tried to set the number as string, which didn't affect the situation in any way
        Name: "test1",
        AdditionalText: "test11"
    },
    {
        Code: 1,
        Name: "test2",
        AdditionalText: "test22"
    },
    {
        Code: 2,
        Name: "test3",
        AdditionalText: "test33"
    }
];
var cbStateModel = new sap.ui.model.json.JSONModel({ items: cbStateItems });

var cbStateTemplate = new sap.ui.core.ListItem({
    key: "{Code}",
    text: "{Name}",
    additionalText: "{AdditionalText}"
});

var cbState = new sap.m.ComboBox({
    // here, all commented lines - I tried to uncomment one or couple of them at a time in different groups of uncommented lines to test (first, first and second, etc.)
    //text: '{state}',
    //selectedKey: '{state}',
    items: {
        path: '/items',
        template: cbStateTemplate,
        //selectedItemId: '{state}',
        templateShareable: false
    },
    showSecondaryValues: true,
    //selectedItemId: '{state}',
    //selectedKey: '{state}',
    //key: '{state}',
    //value: "{Name}",
    selectedKey: function (key) {// here, I thought, that maybe I can implement the binding manually. I know, that this is a prop of type string, but thought, that I could pass it a function, that returns a string - does not get called
        debugger;
        if (typeof (key) !== 'undefined' && key !== null) {
            return cbStateItems[key].Name;
        } else {
            return '0';
        }
    },
    selectionChange: function (oControlEvent) {
        var gewrgter = oModel;
        debugger;
    }
}); //.bindProperty("selectedKey", "state"); //.bindProperty("selectedItemId", "state"); none of those work
debugger;
cbState.setModel(cbStateModel);

var cbStateCol = new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "State" }),
    template: cbState,
    width: gridTestColWidth
});
oTable.addColumn(cbStateCol);
为简单起见,让
dataToShow
中的每个实体如下所示:

oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataToShow); // dataToShow being an array of entities
{
    itemID: '123',
    state: 1 // state is an int column in the database
}
oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "Number of item" }),
    template: new sap.ui.commons.TextView({ text: "{itemID}" }),
    sortProperty: "itemID", // https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/ui/table/demokit/Table.html#__2
    filterProperty: "itemID",
    width: gridTestColWidth
}));
// first, hard-code (for now) the list of possible items
var cbStateItems = [
    {
        Code: 0,
        //Code: '0', // I tried to set the number as string, which didn't affect the situation in any way
        Name: "test1",
        AdditionalText: "test11"
    },
    {
        Code: 1,
        Name: "test2",
        AdditionalText: "test22"
    },
    {
        Code: 2,
        Name: "test3",
        AdditionalText: "test33"
    }
];
var cbStateModel = new sap.ui.model.json.JSONModel({ items: cbStateItems });

var cbStateTemplate = new sap.ui.core.ListItem({
    key: "{Code}",
    text: "{Name}",
    additionalText: "{AdditionalText}"
});

var cbState = new sap.m.ComboBox({
    // here, all commented lines - I tried to uncomment one or couple of them at a time in different groups of uncommented lines to test (first, first and second, etc.)
    //text: '{state}',
    //selectedKey: '{state}',
    items: {
        path: '/items',
        template: cbStateTemplate,
        //selectedItemId: '{state}',
        templateShareable: false
    },
    showSecondaryValues: true,
    //selectedItemId: '{state}',
    //selectedKey: '{state}',
    //key: '{state}',
    //value: "{Name}",
    selectedKey: function (key) {// here, I thought, that maybe I can implement the binding manually. I know, that this is a prop of type string, but thought, that I could pass it a function, that returns a string - does not get called
        debugger;
        if (typeof (key) !== 'undefined' && key !== null) {
            return cbStateItems[key].Name;
        } else {
            return '0';
        }
    },
    selectionChange: function (oControlEvent) {
        var gewrgter = oModel;
        debugger;
    }
}); //.bindProperty("selectedKey", "state"); //.bindProperty("selectedItemId", "state"); none of those work
debugger;
cbState.setModel(cbStateModel);

var cbStateCol = new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "State" }),
    template: cbState,
    width: gridTestColWidth
});
oTable.addColumn(cbStateCol);
因此,每个实体都有一个类型为
int
的属性“state”。 我创建了一个普通的oTable,如下所示:
oTable=newsap.ui.table.table({…})

“itemID”列的定义如下:

oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataToShow); // dataToShow being an array of entities
{
    itemID: '123',
    state: 1 // state is an int column in the database
}
oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "Number of item" }),
    template: new sap.ui.commons.TextView({ text: "{itemID}" }),
    sortProperty: "itemID", // https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/ui/table/demokit/Table.html#__2
    filterProperty: "itemID",
    width: gridTestColWidth
}));
// first, hard-code (for now) the list of possible items
var cbStateItems = [
    {
        Code: 0,
        //Code: '0', // I tried to set the number as string, which didn't affect the situation in any way
        Name: "test1",
        AdditionalText: "test11"
    },
    {
        Code: 1,
        Name: "test2",
        AdditionalText: "test22"
    },
    {
        Code: 2,
        Name: "test3",
        AdditionalText: "test33"
    }
];
var cbStateModel = new sap.ui.model.json.JSONModel({ items: cbStateItems });

var cbStateTemplate = new sap.ui.core.ListItem({
    key: "{Code}",
    text: "{Name}",
    additionalText: "{AdditionalText}"
});

var cbState = new sap.m.ComboBox({
    // here, all commented lines - I tried to uncomment one or couple of them at a time in different groups of uncommented lines to test (first, first and second, etc.)
    //text: '{state}',
    //selectedKey: '{state}',
    items: {
        path: '/items',
        template: cbStateTemplate,
        //selectedItemId: '{state}',
        templateShareable: false
    },
    showSecondaryValues: true,
    //selectedItemId: '{state}',
    //selectedKey: '{state}',
    //key: '{state}',
    //value: "{Name}",
    selectedKey: function (key) {// here, I thought, that maybe I can implement the binding manually. I know, that this is a prop of type string, but thought, that I could pass it a function, that returns a string - does not get called
        debugger;
        if (typeof (key) !== 'undefined' && key !== null) {
            return cbStateItems[key].Name;
        } else {
            return '0';
        }
    },
    selectionChange: function (oControlEvent) {
        var gewrgter = oModel;
        debugger;
    }
}); //.bindProperty("selectedKey", "state"); //.bindProperty("selectedItemId", "state"); none of those work
debugger;
cbState.setModel(cbStateModel);

var cbStateCol = new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "State" }),
    template: cbState,
    width: gridTestColWidth
});
oTable.addColumn(cbStateCol);
对于第二列,我尝试在其中放置一个组合框,如下所示:

oModel = new sap.ui.model.json.JSONModel();
oModel.setData(dataToShow); // dataToShow being an array of entities
{
    itemID: '123',
    state: 1 // state is an int column in the database
}
oTable.addColumn(new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "Number of item" }),
    template: new sap.ui.commons.TextView({ text: "{itemID}" }),
    sortProperty: "itemID", // https://sapui5.netweaver.ondemand.com/sdk/test-resources/sap/ui/table/demokit/Table.html#__2
    filterProperty: "itemID",
    width: gridTestColWidth
}));
// first, hard-code (for now) the list of possible items
var cbStateItems = [
    {
        Code: 0,
        //Code: '0', // I tried to set the number as string, which didn't affect the situation in any way
        Name: "test1",
        AdditionalText: "test11"
    },
    {
        Code: 1,
        Name: "test2",
        AdditionalText: "test22"
    },
    {
        Code: 2,
        Name: "test3",
        AdditionalText: "test33"
    }
];
var cbStateModel = new sap.ui.model.json.JSONModel({ items: cbStateItems });

var cbStateTemplate = new sap.ui.core.ListItem({
    key: "{Code}",
    text: "{Name}",
    additionalText: "{AdditionalText}"
});

var cbState = new sap.m.ComboBox({
    // here, all commented lines - I tried to uncomment one or couple of them at a time in different groups of uncommented lines to test (first, first and second, etc.)
    //text: '{state}',
    //selectedKey: '{state}',
    items: {
        path: '/items',
        template: cbStateTemplate,
        //selectedItemId: '{state}',
        templateShareable: false
    },
    showSecondaryValues: true,
    //selectedItemId: '{state}',
    //selectedKey: '{state}',
    //key: '{state}',
    //value: "{Name}",
    selectedKey: function (key) {// here, I thought, that maybe I can implement the binding manually. I know, that this is a prop of type string, but thought, that I could pass it a function, that returns a string - does not get called
        debugger;
        if (typeof (key) !== 'undefined' && key !== null) {
            return cbStateItems[key].Name;
        } else {
            return '0';
        }
    },
    selectionChange: function (oControlEvent) {
        var gewrgter = oModel;
        debugger;
    }
}); //.bindProperty("selectedKey", "state"); //.bindProperty("selectedItemId", "state"); none of those work
debugger;
cbState.setModel(cbStateModel);

var cbStateCol = new sap.ui.table.Column({
    label: new sap.ui.commons.Label({ text: "State" }),
    template: cbState,
    width: gridTestColWidth
});
oTable.addColumn(cbStateCol);
最后,我调用
oTable.setModel(oModel)
以在网格中显示数据

我从数据库中获取的数据包含所有实体的“State”列中的null、0、1或2值

主要问题:oTable中的所有行都没有在State列和其中的ComboBox中选择任何内容,尽管它们都具有非null值(实际上,只有数据库表中的第一行在列
State
中具有null值)

每次我测试这一点(不同的行未注释),我都会看到数据成功加载到oTable中后的两种情况之一:

  • 当我选择Change一行的值时,它的'Name'属性的值在ComboBox控件的textbox部分显示为文本。但是当我向下滚动行时,这个值看起来像是“卡在”第三行。当我滚动一次(一次滚动4行)时,selectedValue(设为“test33”)离开该行,我在该行中更改了selectionChange,并成为该行之后第4行组合框中的“selected”值。如果我再次滚动,这个值“test33”排序“向下移动”另外4行。当我展开组合框时,我看到高亮显示的项目就是我选择的项目
  • 例如,如果我取消注释此行:
    selectedItemId:'{State}'
    ,进行selectionChange,则组合框的文本框部分中不会显示任何内容,尽管所选项目高亮显示为“selected”
  • 我现在完全糊涂了,因为我期待
    selectedItemId:'{State}'
    selectedKey:'{State}'
    将为我执行“绑定”工作,但他们似乎没有。
    提前感谢您的帮助和建议

    我发布此消息,以防它有用,尽管与@Matbtt或@quality响应的质量相比,它感觉有点脆弱

    选择框有一个.setSelectedItem()函数,该函数需要一个选择列表项作为输入。在这段代码中,我从视图中获得一个选择列表,获取它的第一个条目并将其选中

    var oSelect = this.getView().byId("SubsSelect")
    var oFirstItem = oSelect.getItems()[0];  // I only need to get the first - you may care to iterate the list and match keys to the row etc.
    oSelect.setSelectedItem(oFirstItem)
    oSelect.fireChange(firstItem) // I then invoke the change event to kick off some code.
    

    与您的需求不直接匹配,但可能会有所帮助。

    当您使用多个数据模型时,使用命名模型总是更好的方法。这可能会解决应用程序中的多模型问题。下面是一种使用XML视图的方法

    <mvc:View
    controllerName="com.sap.app.controller.Detail"
        xmlns:mvc="sap.ui.core.mvc"
        xmlns:core="sap.ui.core"
        xmlns:table="sap.ui.table"
        xmlns="sap.m">
        <Page title="Detail section">
            <table:Table 
            rows="{tableModel>/items}">
            <table:columns>
                <table:Column>
                    <Label text="Item ID" />
                    <table:template>
                        <Text text="{tableModel>itemID}"/>
                    </table:template>
                </table:Column>
                <table:Column>
                    <Label text="State" />
                    <table:template>
                        <ComboBox
                            selectedKey="{tableModel>state}"
                            items="{cbState>/items}">
                            <core:Item key="{cbState>Code}" text="{cbState>Name}" additionalText="{cbState>AdditionalText}"/>
                        </ComboBox>
                    </table:template>
                </table:Column>
            </table:columns>
        </table:Table>
        </Page>
    </mvc:View>
    

    谢谢你的帮助!我试过你的解决方案。。。当我在某一行上选择Change并向下滚动时,此时所选值仅保留在该行中。它不会“下移”到另一行。我需要指出的是,当使用
    //selectedKey:'{TableModel>state}',
    时,这不起作用,但是当使用
    selectedItemId:'{TableModel>state}'时,
    。坏消息是,我仍然没有让我们称之为“初始”绑定
    selectedKey:function(key){…}
    仍然不会被调用。我希望
    selectedKey:'{…}'
    selectedItemId:'{…}'
    来做这项工作,但他们还是做不到。好的,我刚刚让它工作了。:)
    selectedKey
    肯定不是一个事件,而是一个属性,这就是问题的原因。现在
    selectedKey=“{tableModel>state}”
    执行此任务。我现在有了初始绑定,以及在特定行上选择Change时的绑定。再一次,谢谢!:)