0

As was mentioned here Dynamic binding of table column and rows, we use two models, but what if we have one?

var aColumnData = [
        {
            qual : "1",
            ol:100
        },
        {
            qual : "2",
            ol:200
        },
        {
            qual : "3",
            ol:300
        },
        {
            qual : "2",
            ol:400
        },
        {
            qual : "5",
            ol:500
        }
    ];

I want to achieve table with 5 columns (ol), but with this method,

var myTable = new sap.ui.table.Table("mT");  
myTable.setModel(vizModel);  

myTable.bindColumns("/", function(index, context) {  

var sColumnId = context.getProperty().ol;  
  var xColumnId = context.getProperty().qual;  

return new sap.ui.table.Column({  
label: sColumnId , 
template: new sap.ui.commons.TextField ({value: xColumnId})
});  
});  
 myTable.bindRows("/"); 

I have 5 duplicate rows, like this:

100     200     300     400     500
1       2       3       4       5
1       2       3       4       5
1       2       3       4       5
1       2       3       4       5
1       2       3       4       5

instead of having this:

100     200     300     400     500
1       2       3       4       5
Community
  • 1
  • 1
placebo
  • 3
  • 1
  • 3

1 Answers1

1

Well, you are binding the rows aggregation to your array of five items. So five rows will be created each with a binding context pointing to its corresponding object in the array. For each row the template controls of the columns are cloned and placed into the cells of the row. These controls can use the binding context of their row for relative data binding paths (without the preceeding /).

In your case the column templates - the TextFields - have a static value each. So the clones for the five rows will have that static value too.

As your TextField values are not bound changes by the user will not be written back to the model.

If you want to have this two-way binding then you will have to transpose your model to one object with many properties.

If you want to have only one row, as a workaround you can bind the rows to a dummy array with one object and use absolute binding paths in your template control.

myTable.bindColumns("/", function(index, context) {  

  var sColumnId = context.getProperty().ol;  
  var xColumnId = context.getProperty().qual;  

  return new sap.ui.table.Column({  
    label: sColumnId , 
    template: new sap.ui.commons.TextField ({value: { path: "/" + index + "/qual" } })
  });  
});  
myTable.bindRows("dummy>/");
myTable.setModel(new sap.ui.model.json.JSONModel([{}]) ,"dummy");
schnoedel
  • 3,918
  • 1
  • 13
  • 17
  • thanks for your detailed answer. I was thinking of this approach, but expected ui5 to be more tricky and deal the problem with factory functions :) Having dummy data creates one minor problem in the future for me: I have to delete it manually every time, when I pass Table's model as an array of parameters to next service-call. Another challenge - is to sort values of the column headers, because now I get 300 500 100 200 400. I think, I should play with model-sorting somehow. – placebo May 11 '16 at 19:44
  • Sorting the columns should indeed be possible using a Sorter: `myTable.bindColumns({path:"/", sorter:[new sap.ui.model.Sorter("qual")], factory: function(index, context) {...}});` – schnoedel May 12 '16 at 09:18