如何防止在 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 事件,suppressKeyboardEventnavigateToNextCellonCellEditingStopped - 仅举几例 - 这是唯一的让它正常工作的东西。

这是我的值解析器,它的价值:

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;   
        }

    }
},