在 JavaScript Controller 中填充后填充 XML table
Populate XML table after filling it in JavaScript Controller
我的 SAPUi5 应用程序中有一个空 XML table:
<m:Table id="testdata3"></m:Table>
在我的 JavaScript 控制器中,我使用 SheetJS 库上传一个 Excel 文件,然后使用 "sheet_to_html" 将数据读入 table。
在调试我的代码时,我将所有数据放在一起,而且我的 console.log 调用在我的 table 的 innerHTML 中显示了数据。但出于某种原因,table 保持为空。所以前端基本上什么都没有发生。我觉得我缺少一个 "return" 或 "populate" 或那个方向的东西来加载 table 新数据。
有什么想法吗?
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
oTable.innerHTML = XLSX.utils.sheet_to_html(worksheet);
console.log(oTable.innerHTML);
}
更新:模型代码
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
var oModel = new sap.ui.model.json.JSONModel();
sap.ui.getCore().setModel(oModel,'myResultModel');
that.getView().byId("testdata3").setModel(oModel);
var oColumns = [];
*// I'm iterating over the column names and pushing them to my table works fine, but I'm then stuck with proceeding and pushing the rest of the data to my table..*
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if( cells[i].indexOf('1') > -1)
{
oColumns.push(worksheet[cells[i]].v);
}
}
var oColumnNames = [];
$.each(oColumns, function(i, value) {
oColumnNames.push({
Text: oColumns[i]
});
});
oModel.setProperty("/columnNames", oColumnNames);
oModel.setProperty("/columnNames", oColumnNames);
var oTemplate = new Column({
header: new Label({
text: "{Text}"
})
});
oTable.bindAggregation("columns", "/columns", oTemplate);
};
};
},
EDIT 这是我尝试的另一种尝试,调试时一切看起来都很好,但 table 仍然是空的..
onXLSXupload : function(e) {
this._import(e.getParameter("files") && e.getParameter("files")[0]);
},
_import : function(file) {
console.log(file);
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
wb.SheetNames.forEach(function(first_sheet_name) {
var roa = XLSX.utils.sheet_to_json(wb.Sheets[first_sheet_name]);
if(roa.length > 0){
result[first_sheet_name] = roa;
}
});
var data = result[Object.keys(result)[0]];
for(var i=0; i<data.length; i++){
var excelRows = new sap.m.ColumnListItem({cells:[
new sap.m.Text({text: data[i][Object.keys(data[i])[0]]}),
new sap.m.Text({text: data[i][Object.keys(data[i])[1]]})
]});
that.getView().byId("testdata3").addItem(excelRows );
}
};
};
},
我只是在努力寻找将项目绑定到我的 table 的正确方法。我想知道它是否与我的 XML 视图或控制器文件有关..
更新 @MatthijsMennen 的回答 现在还在挣扎,因为项目只填充在一列中
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
var aColumns = that.getColumnNames(worksheet);
var aData = that.getRowData(worksheet, result);alert(aData);
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
columns: aColumns,
rows: aData
});
oTable.setModel(oModel);
oTable.bindAggregation("columns", "/columns", function(index, context) {
return new sap.m.Column({
header: new sap.m.Label({
text: context.getObject().columnId
})
});
});
oTable.bindAggregation("items", "/rows", function(index, context){
return new sap.m.ColumnListItem({
cells: [
new sap.m.Text({text: context.getObject().cellId })
]
});
});
};
};
},
getColumnNames: function(worksheet) {
var oColumns = [];
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if (cells[i].indexOf("1") > -1) {
var columnName = worksheet[cells[i]].v;
oColumns.push({
columnId: columnName
});
}
}
return oColumns;
},
getRowData: function(worksheet, result) {
var roa = XLSX.utils.sheet_to_json(worksheet);
if(roa.length > 0){
result[worksheet] = roa;
}
var data = result[Object.keys(result)[0]];
console.log(data.length);
var i; var x;
var oCells = []
for(i = 0; i < data.length; i++){
for(var x = 0; x < data.length; x ++) {
var excelRows = data[i][Object.keys(data[i])[x]];
console.log(data[i][Object.keys(data[i])[x]])
oCells.push({ cellId: excelRows});
}
}
return oCells;
},
使用 for 循环更新列列表项
oTable.bindAggregation("items", "/rows", function(index, context) {
var roa = XLSX.utils.sheet_to_json(worksheet);
if(roa.length > 0){
result[worksheet] = roa;
}
for(var i = 0; i < roa.length; i++){
return new sap.m.ColumnListItem({
cells: [
new Text({ text :context.getObject().cellId })
]
})
};
});
在我的一个项目中,我需要从控制器动态创建 table。
以下是我的做法,希望对您有所帮助:
VIEW
<Table id="tableTask"
inset="false">
<headerToolbar>
<OverflowToolbar id="otbSubheader">
<ToolbarSpacer/>
<SearchField id="taskSearchBox" search="onSearchOrClearPressed" liveChange="onSearchTasks" showSearchButton="false">
<layoutData><OverflowToolbarLayoutData minWidth="200px" maxWidth="300px" shrinkable="true"/></layoutData>
</SearchField>
</OverflowToolbar>
</headerToolbar>
<columns>
<!-- Columns created in controller -->
</columns>
<items>
<ColumnListItem id="columnsListItemTask" press="onPressListItem" type="Navigation">
<cells>
<!-- Cells created in controller -->
</cells>
</ColumnListItem>
</items>
</Table>
控制器
onInit: function(){
...
// Get columns aggregation of table
let oColumns = this.getView().byId('columnsListItemTask');
// Define table cells
let cellToAdd1 = new sap.m.Text('textCell1',{
text: "{path/to/modelValue1}"
});
let cellToAdd2 = new sap.m.Text('textCell2',{
text: "{path/to/modelValue2}"
});
let cellToAdd3 = new sap.m.Text('textCell3',{
text: "{path/to/modelValue3}"
});
let cellToAdd4 = new sap.m.Text('textCell4',{
text: "{path/to/modelValue4}"
});
// Add cells (in this case 4 columns)
oColumns.addCell(cellToAdd1);
oColumns.addCell(cellToAdd2);
oColumns.addCell(cellToAdd3);
oColumns.addCell(cellToAdd4);
var jsonModel = new JSONModel(yourModel);
this.getView().setModel(jsonModel);
// Get Table by id
let oTable = this.getView().byId('tableTask');
oTable.removeAllItems(); //Remove old items if present
oTable.removeAllAggregation(); //Remove aggregations
oTable.bindAggregation('items', {
path:'/rowsData', // field name of you JSONModel containing data rows
template: oColumns, // rowTemplate of cells
});
...
}
更新
您可以执行 for 循环以动态添加任意数量的列:
onInit: 函数(){
...
// Get columns aggregation of table
let oColumns = this.getView().byId('columnsListItemTask');
let cellToAdd;
// This for loop in each columns I need to generate
// (in my case they are defined in a database and I get it with AJAX request)
for(let key in allCellsToGenearte){
cellToAdd = new sap.m.Text({
text: allCellsToGenearte["modelPath"]
});
oColumns.addCell(cellToAdd);
}
// Get Table by id
let oTable = this.getView().byId('tableTask');
oTable.removeAllItems(); //Remove old items if present
oTable.removeAllAggregation(); //Remove aggregations
oTable.bindAggregation('items', {
path:'/rowsData', // field name of JSON Model containing data rows
template: oColumns, // rowTemplate of cells
});
...
}
我在这里用 SheetJS 创建了一个小例子。列名是从工作表中提取的,但您仍然需要从工作表中获取行。我为行添加了一些虚拟数据。
希望这对您有所帮助。
查看
<Table id="testdata3" />
<u:FileUploader change="onChange" buttonText="Upload" />
控制器
onChange: function(oEvent) {
var file = oEvent.getParameter("files")[0];
var oTable = this.byId("testdata3");
var reader = new FileReader();
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var data = e.target.result;
var wb = XLSX.read(data, {
type: "binary"
});
var firstSheetName = wb.SheetNames[0];
var worksheet = wb.Sheets[firstSheetName];
var oModel = new sap.ui.model.json.JSONModel();
var aColumns = that.getColumnNames(worksheet);
var aData = that.getRowData(worksheet);
var aCells = that.getCells(aColumns);
oModel.setData({
columns: aColumns,
rows: aData
});
oTable.setModel(oModel);
oTable.bindAggregation("columns", "/columns", function(index, context) {
return new sap.m.Column({
header: new sap.m.Label({
text: context.getObject().columnId
})
});
});
oTable.bindAggregation("items", "/rows", new sap.m.ColumnListItem({
// CHANGE ACCORDINGLY OR MAKE DYNAMIC
cells: aCells
}));
};
},
getColumnNames: function(worksheet) {
var oColumns = [];
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if (cells[i].indexOf("1") > -1) {
var columnName = worksheet[cells[i]].v;
oColumns.push({
columnId: columnName
});
}
}
return oColumns;
},
getRowData: function() {
var aItems = [];
// DO YOUR THING HERE
aItems[0] = {
value0: "testvalue0",
value1: "testvalue1",
value2: "testvalue2",
value3: "testvalue3",
value4: "testvalue4"
};
return aItems;
},
getCells: function(aColumns) {
var cells = [];
for (var i = 0; i < aColumns.length; i++) {
cells[i] = new sap.m.Text({
text: "{value" + i + "}"
});
}
return cells;
}
Excel 例子
我的 SAPUi5 应用程序中有一个空 XML table:
<m:Table id="testdata3"></m:Table>
在我的 JavaScript 控制器中,我使用 SheetJS 库上传一个 Excel 文件,然后使用 "sheet_to_html" 将数据读入 table。 在调试我的代码时,我将所有数据放在一起,而且我的 console.log 调用在我的 table 的 innerHTML 中显示了数据。但出于某种原因,table 保持为空。所以前端基本上什么都没有发生。我觉得我缺少一个 "return" 或 "populate" 或那个方向的东西来加载 table 新数据。 有什么想法吗?
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
oTable.innerHTML = XLSX.utils.sheet_to_html(worksheet);
console.log(oTable.innerHTML);
}
更新:模型代码
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
var oModel = new sap.ui.model.json.JSONModel();
sap.ui.getCore().setModel(oModel,'myResultModel');
that.getView().byId("testdata3").setModel(oModel);
var oColumns = [];
*// I'm iterating over the column names and pushing them to my table works fine, but I'm then stuck with proceeding and pushing the rest of the data to my table..*
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if( cells[i].indexOf('1') > -1)
{
oColumns.push(worksheet[cells[i]].v);
}
}
var oColumnNames = [];
$.each(oColumns, function(i, value) {
oColumnNames.push({
Text: oColumns[i]
});
});
oModel.setProperty("/columnNames", oColumnNames);
oModel.setProperty("/columnNames", oColumnNames);
var oTemplate = new Column({
header: new Label({
text: "{Text}"
})
});
oTable.bindAggregation("columns", "/columns", oTemplate);
};
};
},
EDIT 这是我尝试的另一种尝试,调试时一切看起来都很好,但 table 仍然是空的..
onXLSXupload : function(e) {
this._import(e.getParameter("files") && e.getParameter("files")[0]);
},
_import : function(file) {
console.log(file);
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
wb.SheetNames.forEach(function(first_sheet_name) {
var roa = XLSX.utils.sheet_to_json(wb.Sheets[first_sheet_name]);
if(roa.length > 0){
result[first_sheet_name] = roa;
}
});
var data = result[Object.keys(result)[0]];
for(var i=0; i<data.length; i++){
var excelRows = new sap.m.ColumnListItem({cells:[
new sap.m.Text({text: data[i][Object.keys(data[i])[0]]}),
new sap.m.Text({text: data[i][Object.keys(data[i])[1]]})
]});
that.getView().byId("testdata3").addItem(excelRows );
}
};
};
},
我只是在努力寻找将项目绑定到我的 table 的正确方法。我想知道它是否与我的 XML 视图或控制器文件有关..
更新 @MatthijsMennen 的回答 现在还在挣扎,因为项目只填充在一列中
_import : function(file) {
var oTable = this.getView().byId('testdata3');
if(file && window.FileReader){
var reader = new FileReader();
var result = {}, data;
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var rawLog = reader.result;
data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
var first_sheet_name = wb.SheetNames[0];
var worksheet = wb.Sheets[first_sheet_name];
var aColumns = that.getColumnNames(worksheet);
var aData = that.getRowData(worksheet, result);alert(aData);
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData({
columns: aColumns,
rows: aData
});
oTable.setModel(oModel);
oTable.bindAggregation("columns", "/columns", function(index, context) {
return new sap.m.Column({
header: new sap.m.Label({
text: context.getObject().columnId
})
});
});
oTable.bindAggregation("items", "/rows", function(index, context){
return new sap.m.ColumnListItem({
cells: [
new sap.m.Text({text: context.getObject().cellId })
]
});
});
};
};
},
getColumnNames: function(worksheet) {
var oColumns = [];
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if (cells[i].indexOf("1") > -1) {
var columnName = worksheet[cells[i]].v;
oColumns.push({
columnId: columnName
});
}
}
return oColumns;
},
getRowData: function(worksheet, result) {
var roa = XLSX.utils.sheet_to_json(worksheet);
if(roa.length > 0){
result[worksheet] = roa;
}
var data = result[Object.keys(result)[0]];
console.log(data.length);
var i; var x;
var oCells = []
for(i = 0; i < data.length; i++){
for(var x = 0; x < data.length; x ++) {
var excelRows = data[i][Object.keys(data[i])[x]];
console.log(data[i][Object.keys(data[i])[x]])
oCells.push({ cellId: excelRows});
}
}
return oCells;
},
使用 for 循环更新列列表项
oTable.bindAggregation("items", "/rows", function(index, context) {
var roa = XLSX.utils.sheet_to_json(worksheet);
if(roa.length > 0){
result[worksheet] = roa;
}
for(var i = 0; i < roa.length; i++){
return new sap.m.ColumnListItem({
cells: [
new Text({ text :context.getObject().cellId })
]
})
};
});
在我的一个项目中,我需要从控制器动态创建 table。
以下是我的做法,希望对您有所帮助:
VIEW
<Table id="tableTask"
inset="false">
<headerToolbar>
<OverflowToolbar id="otbSubheader">
<ToolbarSpacer/>
<SearchField id="taskSearchBox" search="onSearchOrClearPressed" liveChange="onSearchTasks" showSearchButton="false">
<layoutData><OverflowToolbarLayoutData minWidth="200px" maxWidth="300px" shrinkable="true"/></layoutData>
</SearchField>
</OverflowToolbar>
</headerToolbar>
<columns>
<!-- Columns created in controller -->
</columns>
<items>
<ColumnListItem id="columnsListItemTask" press="onPressListItem" type="Navigation">
<cells>
<!-- Cells created in controller -->
</cells>
</ColumnListItem>
</items>
</Table>
控制器
onInit: function(){
...
// Get columns aggregation of table
let oColumns = this.getView().byId('columnsListItemTask');
// Define table cells
let cellToAdd1 = new sap.m.Text('textCell1',{
text: "{path/to/modelValue1}"
});
let cellToAdd2 = new sap.m.Text('textCell2',{
text: "{path/to/modelValue2}"
});
let cellToAdd3 = new sap.m.Text('textCell3',{
text: "{path/to/modelValue3}"
});
let cellToAdd4 = new sap.m.Text('textCell4',{
text: "{path/to/modelValue4}"
});
// Add cells (in this case 4 columns)
oColumns.addCell(cellToAdd1);
oColumns.addCell(cellToAdd2);
oColumns.addCell(cellToAdd3);
oColumns.addCell(cellToAdd4);
var jsonModel = new JSONModel(yourModel);
this.getView().setModel(jsonModel);
// Get Table by id
let oTable = this.getView().byId('tableTask');
oTable.removeAllItems(); //Remove old items if present
oTable.removeAllAggregation(); //Remove aggregations
oTable.bindAggregation('items', {
path:'/rowsData', // field name of you JSONModel containing data rows
template: oColumns, // rowTemplate of cells
});
...
}
更新
您可以执行 for 循环以动态添加任意数量的列:
onInit: 函数(){
...
// Get columns aggregation of table
let oColumns = this.getView().byId('columnsListItemTask');
let cellToAdd;
// This for loop in each columns I need to generate
// (in my case they are defined in a database and I get it with AJAX request)
for(let key in allCellsToGenearte){
cellToAdd = new sap.m.Text({
text: allCellsToGenearte["modelPath"]
});
oColumns.addCell(cellToAdd);
}
// Get Table by id
let oTable = this.getView().byId('tableTask');
oTable.removeAllItems(); //Remove old items if present
oTable.removeAllAggregation(); //Remove aggregations
oTable.bindAggregation('items', {
path:'/rowsData', // field name of JSON Model containing data rows
template: oColumns, // rowTemplate of cells
});
...
}
我在这里用 SheetJS 创建了一个小例子。列名是从工作表中提取的,但您仍然需要从工作表中获取行。我为行添加了一些虚拟数据。
希望这对您有所帮助。
查看
<Table id="testdata3" />
<u:FileUploader change="onChange" buttonText="Upload" />
控制器
onChange: function(oEvent) {
var file = oEvent.getParameter("files")[0];
var oTable = this.byId("testdata3");
var reader = new FileReader();
var that = this;
reader.readAsBinaryString(file);
reader.onload = function(e) {
var data = e.target.result;
var wb = XLSX.read(data, {
type: "binary"
});
var firstSheetName = wb.SheetNames[0];
var worksheet = wb.Sheets[firstSheetName];
var oModel = new sap.ui.model.json.JSONModel();
var aColumns = that.getColumnNames(worksheet);
var aData = that.getRowData(worksheet);
var aCells = that.getCells(aColumns);
oModel.setData({
columns: aColumns,
rows: aData
});
oTable.setModel(oModel);
oTable.bindAggregation("columns", "/columns", function(index, context) {
return new sap.m.Column({
header: new sap.m.Label({
text: context.getObject().columnId
})
});
});
oTable.bindAggregation("items", "/rows", new sap.m.ColumnListItem({
// CHANGE ACCORDINGLY OR MAKE DYNAMIC
cells: aCells
}));
};
},
getColumnNames: function(worksheet) {
var oColumns = [];
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(cells).length; i++) {
if (cells[i].indexOf("1") > -1) {
var columnName = worksheet[cells[i]].v;
oColumns.push({
columnId: columnName
});
}
}
return oColumns;
},
getRowData: function() {
var aItems = [];
// DO YOUR THING HERE
aItems[0] = {
value0: "testvalue0",
value1: "testvalue1",
value2: "testvalue2",
value3: "testvalue3",
value4: "testvalue4"
};
return aItems;
},
getCells: function(aColumns) {
var cells = [];
for (var i = 0; i < aColumns.length; i++) {
cells[i] = new sap.m.Text({
text: "{value" + i + "}"
});
}
return cells;
}
Excel 例子