【问题标题】:How can I reset an input field using Angularjs when the backspace/delete keys are pressed?当按下退格/删除键时,如何使用 Angularjs 重置输入字段?
【发布时间】:2016-05-24 21:37:31
【问题描述】:

当按下退格/删除键时,如何使用 Angularjs 重置输入字段?

我已经使用了这个awesome directive,它运行良好,除非用户使用退格键或删除键清除该字段。然后验证会阻止用户提交表单(使用 Chrome v.50.0.2661.102)。

我尝试修改指令,但没有成功。非常感谢任何帮助。

这是我在 el.bind() 中修改的指令:

angular.module(myApp)
.directive('resetField', 
function resetField($compile, $timeout) {
return {
    require: 'ngModel',
    scope: {},
    transclusion: true,
    link: function (scope, el, attrs, ctrl) {
        // limit to input element of specific types
        var inputTypes = /text|search|tel|url|email|password/i;
        if (el[0].nodeName !== "INPUT")
            throw new Error("resetField is limited to input elements");
        if (!inputTypes.test(attrs.type))
            throw new Error("Invalid input type for resetField: " + attrs.type);

        // compiled reset icon template
        var template = $compile('<i ng-show="enabled" ng-mousedown="reset()" class="fa fa-times-circle"></i>')(scope);
        el.addClass('reset-field');
        el.after(template);

        scope.reset = function () {
            ctrl.$setViewValue(null);
            ctrl.$render();
            $timeout(function () {
                el[0].focus();
            }, 0, false);
            scope.enabled = false;
        };

        el.bind('input', function () {    

          //I added this snippet since the directive on its own works so  
          // well, (thought scope.reset() above would do the trick) but it                   
          //doesn't pass the validations... thus the remaining code
            if (ctrl.$isEmpty(el.val())) {      
                scope.reset();     

                el[0].classList.remove('ng-dirty');
                el[0].classList.remove('ng-touched');
                el[0].classList.add('ng-pristine');
                el[0].classList.remove('ng-invalid-required');
                el[0].classList.add('ng-pristine');
                el[0].classList.add('ng-valid');

            } else {
                scope.enabled = !ctrl.$isEmpty(el.val());
            }
            scope.$apply();
        })
        .bind('focus', function () {
            $timeout(function () {
                scope.enabled = !ctrl.$isEmpty(el.val());
                scope.$apply();
            }, 0, false);
        })
        .bind('blur', function () {           
            $timeout(function () {
                scope.enabled = false;                    
            }, 0, false);

        });
    }
};
};
);

html 仍然显示 ng-invalid-required,因为已用退格键重置的依赖字段不为空。

如果我调用与单击“X”完全相同的调用,为什么它的功能不一样?

【问题讨论】:

    标签: javascript angularjs validation field directive


    【解决方案1】:

    有效性设置存储在输入指令的控制器中,因此删除 HTML 中的类名并不重要——它们只会在下一个摘要期间重新添加。

    但是,您可以访问指令中的 ngModel controller - 作为 ctrl 传递到 link() 函数 - 因此您可以调用那里的方法来手动“设置”其有效性/原始性。

    这是一个快速演示(原始指令作者的示例,加上您上面的代码,已修改):http://jsbin.com/wuwezelige/1/edit?html,js,output

    我已将第一个字段设为必填字段,并且它还有一个 ng-pattern 正则表达式,它必须匹配才有效。当您退格时,字段类会重置以将其标记为原始有效

    希望这会有所帮助。

    参考:
    https://docs.angularjs.org/api/ng/type/ngModel.NgModelController https://docs.angularjs.org/api/ng/type/form.FormController

    【讨论】:

    • 感谢您的帮助。这很有意义。不幸的是,它在我的情况下不起作用,因为正如您所说,它“在下一个摘要中重新添加”。这解决了一个巨大的谜团,因为两个输入相互依赖,每当我清除一个,然后清除另一个时,第一个再次无效。有趣的是,该指令的 ng-click 工作正常。不过,你回答了我的问题!
    • 嗯。 ngModel 控制器上的 $setValidity 和 $setPristine() 函数应该可以完成这项工作。你可以发送一个链接到你的代码/演示吗?
    猜你喜欢
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 2016-06-04
    • 2016-02-13
    • 2017-08-04
    • 1970-01-01
    • 2015-05-26
    • 2015-07-28
    相关资源
    最近更新 更多