Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 重新验证选择元素的更改事件的输入_Javascript_Angularjs - Fatal编程技术网

Javascript 重新验证选择元素的更改事件的输入

Javascript 重新验证选择元素的更改事件的输入,javascript,angularjs,Javascript,Angularjs,我正在编写一个AngularJS应用程序,在这个应用程序中有一个域管理工具。 当选择域时,我在表中生成域记录,让用户编辑每一行。由于字段是动态创建的,我使用ng表单来单独验证每一行,因为它们共享相同的名称 每个域记录都有一个IP、CNAME等内容字段。我使用从函数生成的正则表达式模式验证此字段,该函数基于选择的记录类型a、CNAME、TXT等 问题是,当我编辑一条A记录,然后将记录类型更改为CNAME时,表单仍然有效,因为没有对内容字段执行新的验证。对我来说,重新验证它的唯一方法是开始在内容字段

我正在编写一个AngularJS应用程序,在这个应用程序中有一个域管理工具。 当选择域时,我在表中生成域记录,让用户编辑每一行。由于字段是动态创建的,我使用ng表单来单独验证每一行,因为它们共享相同的名称

每个域记录都有一个IP、CNAME等内容字段。我使用从函数生成的正则表达式模式验证此字段,该函数基于选择的记录类型a、CNAME、TXT等

问题是,当我编辑一条A记录,然后将记录类型更改为CNAME时,表单仍然有效,因为没有对内容字段执行新的验证。对我来说,重新验证它的唯一方法是开始在内容字段中键入内容,这样就可以正常工作了

查看以下图片:

我在A记录上按编辑,一切看起来都很好:

我将记录类型更改为CNAME,即使正则表达式已更改,表单仍然有效。当我更改类型时,我希望内容1.2.3.4重新验证,因为它是一个新的正则表达式:

我开始在内容字段中键入,现在表单正确地变为无效。我希望在更改记录类型时发生这种情况,而不仅仅是在我再次开始键入时:


我现在选择实际字段,并更改类,使其在正则表达式不匹配时无效。这样,“保存”按钮也会变得无效。这在下拉列表中更改时有效,但它会以某种方式损坏已编译的元素。

我认为解决方案是监视record.type模型,并在更改它时触发新的正则表达式验证。但是为了做到这一点,model record.content已经进行了更改,您可以通过代码来执行该更改。

您可以使用下拉菜单上的指令来执行该操作,如下所示:

angular.module('App').directive('revalidate', function($compile) {
return {
    restrict: 'A',
    link : function (scope, element, attrs) {
      scope.$watch(attrs.ngModel, function (v) {
          var reg = scope.$parent.domainRecordContentRegex[0];
          if(!$(element).parent().next().find('ng-form').find('input').val().match(reg)){
              $compile($('button[type="submit"]').attr('ng-disabled', "true"))(scope);  
          }

        });
      }
    }
});
在该指令中,您正在查看下拉菜单的模型值或接受该指令的元素

如果值更改,指令将获取输入值,并检查该值是否与控制器中定义的正则表达式模式匹配。如果没有,则调用$compile方法将ng disabled属性重新设置为submit按钮

警察又来了

查看文档以详细了解$compile:

希望它能帮助你,如果你需要更多的帮助,问它:我很高兴再次帮助你

快乐编码

更新:

好的,如果你$compile你的输入,输入的值会丢失,因为这个值还没有在作用域上

因此,要在$compile时保留输入值,请执行以下操作:

angular.module('App').directive('revalidate', function($compile, $timeout) {
return {
    restrict: 'A',
    link : function (scope, element, attrs) {
      scope.$watch(attrs.ngModel, function (v) {
          var reg = scope.$parent.domainRecordContentRegex[0];
          if(!$(element).parent().next().find('ng-form').find('input').val().match(reg)){
              var value = $(element).parent().next().find('ng-form').find('input').val();
              $compile($(element).parent().next().find('ng-form').find('input').attr('ng-class', "ng-invalid-pattern"))(scope);
              $timeout(function(){
                $(element).parent().next().find('ng-form').find('input').val(value);
              }, 0);
          }

        });
      }
    }
});
在这里,您将输入的值存储在value var中,然后在$compile之后执行$timeout,延迟为0


在这个$timeout中,返回一个承诺-->异步功能强大的XD,您重新设置了输入值,瞧

要触发验证,请在更改选择时将输入值设置为其值。将您的plunker中的第44行更改为

<select ng-change="domainRecordContentType(record.type);innercContentForm.content.$setViewValue(innercContentForm.content.$viewValue)" ng-init="domainRecordContentType(record.type)" ng-model="record.type" ng-options="c for c in types">
更新的plunker


信用证:

我认为最好的解决方案是创建自己的验证指令:

.指令'myValidRec',函数{ var genRegex=函数类型{/。。。 }; 返回{ 要求:'ngModel', 链接:功能范围、el、属性、ngModel{ var validate=functiondata{ var regex=genRegexscope.$evalattrs.myValidRec; ifregex{ ngModel.$setValidity'record',regex[0].测试数据; } 返回数据; }; //当模型值更改时触发验证 ngModel.$formatters.pushvalidate; ngModel.$parsers.pushvalidate; //当用户更改记录类型时触发验证 作用域$watchattrs.myValidRec,函数{ validatescope.$evalattrs.ngModel; }; } } }; 这使得标记更加清晰:

<td>
  <select ng-model="record.type" ng-options="c for c in types">
  </select>
</td>

<td>
  <ng-form name="innercContentForm">
    <span ng-show="innercContentForm.content.$error.record">
      Pattern error ( {{ record.type }} )
    </span>
    <input type="text" ng-model="record.content" name="content" 
           my-valid-rec="record.type" required />
  </ng-form>
</td>

看看这个plnkr:

你能为这个制作一个plunker或小提琴吗?我在问题的底部添加了一个plunker示例。这是一个小错误,第一个记录内容字段由于正则表达式而被删除。这在真实版本中不会发生,但我没有花更多的时间来修复它,你仍然可以测试这个问题。也许你会有bug,因为我可以测试plunker,我在办公室,我有一个大代理。但这是正确的方法!如果你有麻烦,请告诉我嗨,托马斯,谢谢你的回复。我试过你的密码。问题是表单具有动态创建的字段,每行使用嵌套表单ng表单。如果我编辑两个单独的行,您的代码将重新验证所有内容,而不仅仅是我当前编辑的行。我用一张图片更新了主要问题,以演示你的代码发生了什么。是的,他重新验证了所有内容,因为我的选择器接受了所有输入。你必须做你的个人选择或者我会做的:检查新代码他只重新验证一个输入看起来更好。然而,现在,当我从A变为CNAME时,让我们说CNAME并开始
在字段中键入时,Iam键入时内容字段会自动擦除。。比如www.some-domain。哦,天哪,你真是个明星!谢谢!我的大脑会为我的解决方案而颤抖:这是一个非常简单的解决方案,我喜欢它。不过,我真正的模板和plunker略有不同。在我文章的顶部查看slim模板示例。我在我的真实版本中尝试了这个,但它不起作用。可能是因为ng switch?噢@JoakimB我为你感到抱歉lol我希望你能得到一个比mineDeepak N更简单的解决方案,你能对我上面的问题发表意见吗?@JoakimB,如果你能通过更新plunker来使用与你的原始代码类似的ng switch来重现这个问题,那么调试就更容易了。这真是太棒了,工作得很有魅力!谢谢你joakimbl!
angular.module('App').directive('revalidate', function($compile, $timeout) {
return {
    restrict: 'A',
    link : function (scope, element, attrs) {
      scope.$watch(attrs.ngModel, function (v) {
          var reg = scope.$parent.domainRecordContentRegex[0];
          if(!$(element).parent().next().find('ng-form').find('input').val().match(reg)){
              var value = $(element).parent().next().find('ng-form').find('input').val();
              $compile($(element).parent().next().find('ng-form').find('input').attr('ng-class', "ng-invalid-pattern"))(scope);
              $timeout(function(){
                $(element).parent().next().find('ng-form').find('input').val(value);
              }, 0);
          }

        });
      }
    }
});
<select ng-change="domainRecordContentType(record.type);innercContentForm.content.$setViewValue(innercContentForm.content.$viewValue)" ng-init="domainRecordContentType(record.type)" ng-model="record.type" ng-options="c for c in types">
<td>
  <select ng-model="record.type" ng-options="c for c in types">
  </select>
</td>

<td>
  <ng-form name="innercContentForm">
    <span ng-show="innercContentForm.content.$error.record">
      Pattern error ( {{ record.type }} )
    </span>
    <input type="text" ng-model="record.content" name="content" 
           my-valid-rec="record.type" required />
  </ng-form>
</td>