Javascript 如何验证是否触摸了ng表单

Javascript 如何验证是否触摸了ng表单,javascript,angularjs,validation,typescript,Javascript,Angularjs,Validation,Typescript,我已经创建了一个“wrapper”指令,它作为表单元素包装器起作用。一个或多个输入可以包装在此指令内 指令本身包含ng form指令,因此我可以检查每个实例是否存在错误以及(ng model)输入是否无效 在我的包装器模板中,我希望在以下情况下添加“error”类: 一个或多个输入无效 以及: 表格已提交 或 一个或多个输入被触发 这是我当前的(剥离的)包装器指令: export class FormElementWrapper { public transclude = tru

我已经创建了一个“wrapper”指令,它作为表单元素包装器起作用。一个或多个输入可以包装在此指令内

指令本身包含
ng form
指令,因此我可以检查每个实例是否存在错误以及(ng model)输入是否无效

在我的包装器模板中,我希望在以下情况下添加“error”类:

  • 一个或多个输入无效
  • 以及:
    • 表格已提交
    • 一个或多个输入被触发
这是我当前的(剥离的)包装器指令:

export class FormElementWrapper {
    public transclude = true;

    public template = `
        <div ng-form="formElementWrapper"
             ng-class="{'has-error': showError }" ng-transclude>
        </div>
    `;

    public link = (scope, element, attrs) => {
        // custom keep track of touched
        var touched = false;

        var isSubmitted = function(): boolean {
            var form: any = scope.formElementWrapper;
            return form.$$parentForm.$submitted;
        };

        scope.$watch(() => {
            // show error when:
            // - one ore more inputs are invalid
            // - AND
            // -- form is touched
            // -- OR
            // -- parent form is submitted
            var submitted = isSubmitted();
            return scope.formElementWrapper.$invalid && (touched || submitted);
        }, (val) => {
            scope.showError = val;
        });

        // override $setPristine to reset the custom touched property
        var origPristine = scope.formElementWrapper.$setPristine;
        scope.formElementWrapper.$setPristine = () => {
            touched = false;
            origPristine();
        }

        // bind to blur events of all inputs
        element.on("blur", ":input", () => {
            touched = true;
        });
    }
}
导出类FormElementWrapper{
公共转移=真;
公共模板=`
`;
公共链接=(范围、元素、属性)=>{
//定制跟踪触摸
var=false;
var issubmitt=function():布尔值{
变量形式:any=scope.formElementWrapper;
返回表格$$parentForm.$已提交;
};
范围.$watch(()=>{
//在以下情况下显示错误:
//-一个或多个输入无效
//-及
//——形式被触动
//或者
//--已提交家长表格
var submitted=isSubmitted();
返回范围.formElementWrapper.$invalid&(已提交);
},(val)=>{
scope.ror=val;
});
//重写$setPristine以重置自定义属性
var origPristine=scope.formElementWrapper.$setPristine;
scope.formElementWrapper.$setPristine=()=>{
触摸=假;
奥瑞普汀();
}
//绑定到所有输入的模糊事件
元素。在(“模糊”上,“:输入”,()=>{
触摸=真实;
});
}
}

问题:我如何知道是否有一个或多个元素被触摸?ngFormController没有该属性。目前我绑定到输入的
blur
事件,但我可以想象使用
ng model
的其他指令本身不一定是输入。

基本上可以使用未触及的oposite的否定,即
$pristine
。因此,您可以使用
检查它,如果(!form.$pristine)
表示该表单已被触摸

根据,如果用户尚未与表单交互,
$pristine
True

但是,如果您想将
NgModelController.$touch
扩展到FormController,则当任何元素变得模糊时,只需将
$touch=true
添加到表单中即可。当元素被
模糊
事件触发时,可以使用与
ngModel
并发的指令并更改其
FormController.$toucted
值来完成此操作

下面的示例实现了此解决方案

angular.module('app',[])
.directive('ngModel',function(){
返回{
限制:“A”,
要求:['^?表格'],
优先权:1000,
链接:功能(范围、要素、属性、ctrls){
var ngFormCtrl=ctrls[0];
if(ngFormCtrl){
元素on('blur',函数onBlurEvent(){
作用域$apply(函数(){
ngFormCtrl.$toucted=true;
元素关闭(“模糊”,开启模糊事件);
});
});
}
}
};
})
.controller('myController',函数($rootScope){
var$ctrl=this;
$ctrl.model={
姓名:'lenny',
年龄:23
};
});
元素(文档).ready(函数(){
引导(文档,['app']);
});

姓名:
年龄:
{{$ctrl.myForm.$toucted?'toucted':'untoucted'}

谢谢您的回答。我尝试这样做是因为它被记录为“与表单交互”,但它似乎与
$dirty
标志相反,而不是
$toucted
是的,这意味着表单对象(模型)不是DOM输入元素。@devqon实际上,由于ngModelController toucted不是内置在ngFormController上的,所以被触摸,如果你想要它,它必须被实现(顺便说一句,这并不困难)。这看起来很不错!有一个问题:你为什么要在之后解开模糊的带子?@devqon,因为一旦它被触动,你就不再需要那个听众了。但这根本没什么区别,只是少了一个听众。我也用了一种不推荐的方式,我更新了我的答案,改为使用
off()