如何防止在 ag-grid 中使用自定义 vue 组件验证错误时关闭单元格编辑模式
How to prevent closing of cell edit mode on validation errors with custom vue components in ag-grid
我已经成功地将我自己的组件呈现为 cellEditor,并且在休假时我希望它尝试验证值并在失败时阻止关闭。
如果我查看 this then https://www.ag-grid.com/javascript-grid-cell-editing/#editing-api,可以看到用于编辑的可取消回调函数。但是在这个回调函数中有没有办法访问当前实例化的组件?我认为这将是处理此问题的最简单方法。
我正在使用 vee-validate,所以验证函数是异步的,请记住。
我有一个类似的问题 - 尽管在 AngularJS 和 ag-grid 的非 Angular 模式中 - 我需要在单元格编辑器未通过验证时阻止导航。
文档不是很详细,所以最后我添加了一个自定义单元格编辑器,其中包含一个围绕输入字段的表单(以处理诸如红色突出显示等细节),然后使用 Angular JS 验证。这让我到目前为止,但关键部分是试图防止用户在值无效时跳出或离开,这样用户至少可以解决问题。
我通过在添加单元格时添加一个值解析器来做到这一点,然后在其中如果根据各种规则该值无效,则抛出异常。不理想,我知道 - 但它 确实 防止 ag-grid 试图离开单元。
我尝试了很多方法来解决这个问题 - 使用 tabToNextCell
事件,suppressKeyboardEvent
、navigateToNextCell
、onCellEditingStopped
- 仅举几例 - 这是唯一的让它正常工作的东西。
这是我的值解析器,它的价值:
var codeParser = function (args) {
var cellEditor = _controller.currentCellEditor.children['codeValue'];
var paycodeId = +args.colDef.field;
var paycodeInfo = _controller.paycodes.filter(function (f) { return f.id === paycodeId; })[0];
// Check against any mask
if (paycodeInfo && paycodeInfo.mask) {
var reg = new RegExp("^" + paycodeInfo.mask + '$');
var match = args.newValue.match(reg);
if (!match) {
$mdToast.show($mdToast.simple().textContent('Invalid value - does not match paycode format.').position('top right').toastClass('errorToast'))
.then(function(r) {
_controller.currentCellEditor.children['codeValue'].focus();
});
throw 'Invalid value - does not match paycode format.';
}
}
return true;
};
_controller.currentCellEditor
值是在单元格编辑器组件的初始化期间设置的。我这样做是为了在 toast 中显示错误后重新调整控件的焦点:
CodeValueEditor.prototype.init = function (params) {
var form = document.createElement('form');
form.setAttribute('id', 'mainForm');
form.setAttribute('name', 'mainForm');
var input = document.createElement('input');
input.classList.add('ag-cell-edit-input');
input.classList.add('paycode-editor');
input.setAttribute('name', 'codeValue');
input.setAttribute('id', 'codeValue');
input.tabIndex = "0";
input.value = params.value;
if (params.mask) {
input.setAttribute('data-mask', params.mask);
input.setAttribute('ng-pattern','/^' + params.mask + '$/');
input.setAttribute('ng-class',"{'pattern-error': mainForm.codeValue.$error.pattern}");
input.setAttribute('ng-model', 'ctl.currentValue');
}
form.appendChild(input);
this.container = form;
$compile(this.container)($scope);
_controller.currentValue = null;
// This is crucial - we can then reference the container in
// the parser later on to refocus the control
_controller.currentCellEditor = this.container;
$scope.$digest();
};
然后在网格选项中清空onCellEditingStopped
事件:
onCellEditingStopped: function (event) {
$scope.$apply(function() {
_controller.currentCellEditor = null;
});
},
我知道它不是专门针对您的组件 (Vue.js),但希望它能对其他人有所帮助。如果有人有更好的方法,我会洗耳恭听,因为我不喜欢抛出不必要的异常!
使用整行编辑。
创建一个全局变量,如
var problemRow = -1;
然后订阅此活动:
onRowEditingStarted: function (event) {
if (problemRow!=-1 && event.rowIndex!=problemRow) {
gridOptions.api.stopEditing();
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
},
onRowEditingStopped: function (event) {
if (problemRow==-1) {
if (event.data.firstName != "your validation") {
problemRow = event.rowIndex
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
}
if (problemRow == event.rowIndex) {
if (event.data.firstName != "your validation") {
problemRow = event.rowIndex
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
else{
problemRow=-1;
}
}
},
我已经成功地将我自己的组件呈现为 cellEditor,并且在休假时我希望它尝试验证值并在失败时阻止关闭。
如果我查看 this then https://www.ag-grid.com/javascript-grid-cell-editing/#editing-api,可以看到用于编辑的可取消回调函数。但是在这个回调函数中有没有办法访问当前实例化的组件?我认为这将是处理此问题的最简单方法。
我正在使用 vee-validate,所以验证函数是异步的,请记住。
我有一个类似的问题 - 尽管在 AngularJS 和 ag-grid 的非 Angular 模式中 - 我需要在单元格编辑器未通过验证时阻止导航。
文档不是很详细,所以最后我添加了一个自定义单元格编辑器,其中包含一个围绕输入字段的表单(以处理诸如红色突出显示等细节),然后使用 Angular JS 验证。这让我到目前为止,但关键部分是试图防止用户在值无效时跳出或离开,这样用户至少可以解决问题。
我通过在添加单元格时添加一个值解析器来做到这一点,然后在其中如果根据各种规则该值无效,则抛出异常。不理想,我知道 - 但它 确实 防止 ag-grid 试图离开单元。
我尝试了很多方法来解决这个问题 - 使用 tabToNextCell
事件,suppressKeyboardEvent
、navigateToNextCell
、onCellEditingStopped
- 仅举几例 - 这是唯一的让它正常工作的东西。
这是我的值解析器,它的价值:
var codeParser = function (args) {
var cellEditor = _controller.currentCellEditor.children['codeValue'];
var paycodeId = +args.colDef.field;
var paycodeInfo = _controller.paycodes.filter(function (f) { return f.id === paycodeId; })[0];
// Check against any mask
if (paycodeInfo && paycodeInfo.mask) {
var reg = new RegExp("^" + paycodeInfo.mask + '$');
var match = args.newValue.match(reg);
if (!match) {
$mdToast.show($mdToast.simple().textContent('Invalid value - does not match paycode format.').position('top right').toastClass('errorToast'))
.then(function(r) {
_controller.currentCellEditor.children['codeValue'].focus();
});
throw 'Invalid value - does not match paycode format.';
}
}
return true;
};
_controller.currentCellEditor
值是在单元格编辑器组件的初始化期间设置的。我这样做是为了在 toast 中显示错误后重新调整控件的焦点:
CodeValueEditor.prototype.init = function (params) {
var form = document.createElement('form');
form.setAttribute('id', 'mainForm');
form.setAttribute('name', 'mainForm');
var input = document.createElement('input');
input.classList.add('ag-cell-edit-input');
input.classList.add('paycode-editor');
input.setAttribute('name', 'codeValue');
input.setAttribute('id', 'codeValue');
input.tabIndex = "0";
input.value = params.value;
if (params.mask) {
input.setAttribute('data-mask', params.mask);
input.setAttribute('ng-pattern','/^' + params.mask + '$/');
input.setAttribute('ng-class',"{'pattern-error': mainForm.codeValue.$error.pattern}");
input.setAttribute('ng-model', 'ctl.currentValue');
}
form.appendChild(input);
this.container = form;
$compile(this.container)($scope);
_controller.currentValue = null;
// This is crucial - we can then reference the container in
// the parser later on to refocus the control
_controller.currentCellEditor = this.container;
$scope.$digest();
};
然后在网格选项中清空onCellEditingStopped
事件:
onCellEditingStopped: function (event) {
$scope.$apply(function() {
_controller.currentCellEditor = null;
});
},
我知道它不是专门针对您的组件 (Vue.js),但希望它能对其他人有所帮助。如果有人有更好的方法,我会洗耳恭听,因为我不喜欢抛出不必要的异常!
使用整行编辑。 创建一个全局变量,如
var problemRow = -1;
然后订阅此活动:
onRowEditingStarted: function (event) {
if (problemRow!=-1 && event.rowIndex!=problemRow) {
gridOptions.api.stopEditing();
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
},
onRowEditingStopped: function (event) {
if (problemRow==-1) {
if (event.data.firstName != "your validation") {
problemRow = event.rowIndex
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
}
if (problemRow == event.rowIndex) {
if (event.data.firstName != "your validation") {
problemRow = event.rowIndex
gridOptions.api.startEditingCell({
rowIndex: problemRow,
colKey: 'the column you want to focus',
});
}
else{
problemRow=-1;
}
}
},