为什么 Interactive Grid 进程不保存使用 JavaScript 中的模型接口设置的值?
Why doesn't Interactive Grid process save values set using the Model interface in JavaScript?
我正在编写一个 JavaScript 函数,以允许使用 Oracle Application Express 21.1 构建的应用程序的用户将数据从 Excel 电子表格粘贴到交互式网格中并保存数据。使用 APEX JavaScript API 我可以用数据更新交互式网格的模型;粘贴的值显示正确,当我随后访问模型时返回正确的值。
但是,当保存交互式网格时,这些值不会保存到基础数据库中 table。发生的事情是:
- JavaScript 函数更新的空列保持为空
- 具有现有数据的列然后由 JavaScript 函数设置为空
- 空列和包含用户随后正常更改的现有数据的列已正确更新
- 最初由 JavaScript 函数设置然后由用户正常更改的列已正确更新
网格是基于默认EMPtable的简单交互式网格区域,静态ID为EmployeeGrid,并使用创建网格时自动生成的交互式网格进程进行保存。
我在页面加载时执行部分输入了以下代码:
$("#EmployeesGrid_ig").on('paste', onPaste);
我在函数和全局变量声明部分输入了以下代码:
function onPaste(e) {
if (!e.originalEvent.clipboardData ||
!e.originalEvent.clipboardData.items) return;
let items = e.originalEvent.clipboardData.items;
let data;
for (let i = 0; i < items.length; i++) {
if (items[i].type == 'text/plain') {
data = items[i];
break;
}
}
if (!data) return;
data.getAsString(function(text) {
// Split the clipboard data into rows.
text = text.replace(/\r/g, '').trim('\n');
let rowsOfText = text.split('\n');
let rows = [];
// Iterate over each row of text and push the trimmed data into rows[]
rowsOfText.forEach(function(rowOfText) {
let row = rowOfText.split('\t').map(function(colAsText) {
return colAsText.trim().replace(/^"(.*)"$/, '');
});
rows.push(row);
});
// We get the focused element (i.e. where the user wants to paste).
let $focused = $('.is-focused');
// We get metadata from the Interactive Grid.
let rowId = $focused.closest('tr').data('id');
let columnIndex = $focused.index();
let headerIndex = $focused.closest('table').find('th').eq(columnIndex).data('idx');
let ig$ = apex.region("EmployeesGrid").widget();
let grid = ig$.interactiveGrid("getCurrentView");
let model = grid.model;
let columns = grid.getColumns();
let record = model.getRecord(rowId);
//Map visible columns
let visibleColumns = columns.filter(function (val) { return !val.hidden; });
visibleColumns.sort(function(a,b){return a.index - b.index;});
// Complete the Promise after the grid is out of editing mode.
rows.forEach(function(row) {
row.forEach(function(value, offset) {
if (record !== null) {
visibleColumns.forEach(function(column, visColIdx) {
if (visColIdx === (headerIndex + offset)) {
if (model.allowEdit(record)) {
model.setValue(record, column.property, Number(value));
}
}
});
}
});
// To change record, get current record index and then get next record.
let recordIndex = model.indexOf(record);
record = model.recordAt(recordIndex + 1);
});
});
}
我创建了一个 sample application on apex.oracle.com 来演示该行为,请注意我已将网格设置为仅允许更新现有行,并且只能更新 Sal 和 Comm 编号列。
我在 Oracle Communities 上发现了一个类似的问题,其中用户 Woodrow 可以直观地看到在交互式网格列中自动更新的值,但在提交页面时这些值不存在。
他们找到的答案是将值设置为字符串:
model.setValue(record, column.property, value);
而不是数字:
model.setValue(record, column.property, Number(value));
即使列在 APEX 中被声明为 'Number' 列,这也是必要的。
另一种方法是使用 apex.locale JSAPI,它是更 APEX 原生的方式,不会在未来的 APEX 升级中引起问题
var number = apex.locale.toNumber( "1,234.56" );
number = apex.locale.toNumber( ",234.56", "FML999G999G990D00" );
number = apex.locale.toNumber( "34.56", "FML999G999G990D00" );
看看这个
https://docs.oracle.com/en/database/oracle/application-express/21.2/aexjs/apex.locale.html#.toNumber
我正在编写一个 JavaScript 函数,以允许使用 Oracle Application Express 21.1 构建的应用程序的用户将数据从 Excel 电子表格粘贴到交互式网格中并保存数据。使用 APEX JavaScript API 我可以用数据更新交互式网格的模型;粘贴的值显示正确,当我随后访问模型时返回正确的值。
但是,当保存交互式网格时,这些值不会保存到基础数据库中 table。发生的事情是:
- JavaScript 函数更新的空列保持为空
- 具有现有数据的列然后由 JavaScript 函数设置为空
- 空列和包含用户随后正常更改的现有数据的列已正确更新
- 最初由 JavaScript 函数设置然后由用户正常更改的列已正确更新
网格是基于默认EMPtable的简单交互式网格区域,静态ID为EmployeeGrid,并使用创建网格时自动生成的交互式网格进程进行保存。
我在页面加载时执行部分输入了以下代码:
$("#EmployeesGrid_ig").on('paste', onPaste);
我在函数和全局变量声明部分输入了以下代码:
function onPaste(e) {
if (!e.originalEvent.clipboardData ||
!e.originalEvent.clipboardData.items) return;
let items = e.originalEvent.clipboardData.items;
let data;
for (let i = 0; i < items.length; i++) {
if (items[i].type == 'text/plain') {
data = items[i];
break;
}
}
if (!data) return;
data.getAsString(function(text) {
// Split the clipboard data into rows.
text = text.replace(/\r/g, '').trim('\n');
let rowsOfText = text.split('\n');
let rows = [];
// Iterate over each row of text and push the trimmed data into rows[]
rowsOfText.forEach(function(rowOfText) {
let row = rowOfText.split('\t').map(function(colAsText) {
return colAsText.trim().replace(/^"(.*)"$/, '');
});
rows.push(row);
});
// We get the focused element (i.e. where the user wants to paste).
let $focused = $('.is-focused');
// We get metadata from the Interactive Grid.
let rowId = $focused.closest('tr').data('id');
let columnIndex = $focused.index();
let headerIndex = $focused.closest('table').find('th').eq(columnIndex).data('idx');
let ig$ = apex.region("EmployeesGrid").widget();
let grid = ig$.interactiveGrid("getCurrentView");
let model = grid.model;
let columns = grid.getColumns();
let record = model.getRecord(rowId);
//Map visible columns
let visibleColumns = columns.filter(function (val) { return !val.hidden; });
visibleColumns.sort(function(a,b){return a.index - b.index;});
// Complete the Promise after the grid is out of editing mode.
rows.forEach(function(row) {
row.forEach(function(value, offset) {
if (record !== null) {
visibleColumns.forEach(function(column, visColIdx) {
if (visColIdx === (headerIndex + offset)) {
if (model.allowEdit(record)) {
model.setValue(record, column.property, Number(value));
}
}
});
}
});
// To change record, get current record index and then get next record.
let recordIndex = model.indexOf(record);
record = model.recordAt(recordIndex + 1);
});
});
}
我创建了一个 sample application on apex.oracle.com 来演示该行为,请注意我已将网格设置为仅允许更新现有行,并且只能更新 Sal 和 Comm 编号列。
我在 Oracle Communities 上发现了一个类似的问题,其中用户 Woodrow 可以直观地看到在交互式网格列中自动更新的值,但在提交页面时这些值不存在。
他们找到的答案是将值设置为字符串:
model.setValue(record, column.property, value);
而不是数字:
model.setValue(record, column.property, Number(value));
即使列在 APEX 中被声明为 'Number' 列,这也是必要的。
另一种方法是使用 apex.locale JSAPI,它是更 APEX 原生的方式,不会在未来的 APEX 升级中引起问题
var number = apex.locale.toNumber( "1,234.56" );
number = apex.locale.toNumber( ",234.56", "FML999G999G990D00" );
number = apex.locale.toNumber( "34.56", "FML999G999G990D00" );
看看这个 https://docs.oracle.com/en/database/oracle/application-express/21.2/aexjs/apex.locale.html#.toNumber