Angularjs 验证对于 1.3.0 和 1.2.6 的行为有所不同

标签 angularjs angularjs-directive angularjs-validation

我希望创建一个自定义指令,它呈现为输入类型元素。该指令应该重用 angularjs 验证框架。以下是我创建的 custom-input 指令的实际操作:

<!doctype html>
<html ng-app="validationApp">
<body>
  <div class="container" ng-controller="ValidationController as validationController">
    <form name="myForm">
        {{employee | json}}
    <custom-input ng-required="true" ng-model="employee.name" name="employee.name" id="employeeName" ng-pattern="/^[0-9]{1,7}$/"/></custom-input>
    <span ng-show="myForm['employee.name'].$error.required">This is a required field</span>
    <span ng-show="myForm['employee.name'].$error.pattern">This is a invalid field</span>
    </form>
  </div>
  <script type="text/ng-template" id="/templates/customInput.html">
    <div>
        <input type="text" name="{{name}}" ng-model="newInput" id="{{id}}">
    </div>
  </script>
  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js"></script>
</body>

</html>

对应的javascript是:

angular.module('validationApp', [])
.controller("ValidationController", function(){

})
.directive("customInput", function(){
    return {
        restrict: "E",
        require : "ngModel",
        replace: "true",
        templateUrl : "/templates/customInput.html",
        scope : {
            id : "@", //bind id to scope
            name : "@" //bind name to scope
        },
        link: function(scope, element, attrs, ngModelCtrl){
            //When newInput is updated, update the model of original input
             scope.$watch('newInput', function(newValue){
                ngModelCtrl.$setViewValue(newValue);
            });

            //On first load, get the initial value of original input's model and assign it to new input's model
            ngModelCtrl.$render = function(){
                var viewValue = ngModelCtrl.$viewValue;
                if(viewValue){
                    scope.newInput = viewValue;
                }
            }
        }
    }
});

我正在尝试对此自定义输入应用ng-requiredng-pattern验证。我遇到两个问题:

  1. 在 angularjs 1.2.6 中,我可以在 custom-input 中触发 ng-required 验证,但在 1.3.0 中,验证不会被触发。
  2. 我无法在两个版本中触发 ng-pattern 验证。

我的理解是 ngModelController$setViewValue 将触发所有验证。上面是一个人为的示例,我的实际用例是创建一个自定义指令,为 SSN 呈现三个输入框。

以下分别是 1.2.6 和 1.3.0 的 plunker 链接:

Angularjs 1.2.6 Angularjs 1.3.0

最佳答案

  1. 要使 ng-required 正常工作,不要在内部输入表单的输入上使用相同的名称。我似乎在 Angular 1.3 中,这会覆盖附加到您的自定义输入的注册ngModelController

    因此指令的模板可以是

    <div>
      <input type="text" ng-model="newInput" id="{{id}}">
    </div>
    

    这可以在 http://plnkr.co/edit/TqMkxV?p=preview 处看到。 .

    (另外,不知道为什么这里需要 id...)

  2. 我认为(但我不确定)在 1.2.6 ngPattern 中仅适用于 input 元素,而在 1.3 中它是一个单独的指令,集成了与 ngModel.另外,让它在 1.3 中工作

    • 使用 pattern 而不是 ng-pattern,即使文档建议 ng-pattern 应该可以工作。
    • 如果您直接在模板中编写模式,请勿将其包装在 / ... / 中。因此,查找恰好 5 位数字的正确用法是 pattern="^\d{5}$"。这些文档在这方面具有误导性。

      您修改后的 1.3 示例以及 pattern 的工作示例可以在 http://plnkr.co/edit/1zSiJI?p=preview 中查看。

评论后编辑:

  • 如果您确实希望名称出现在内部指令上,并且与父元素名称相同(例如,使用标准整页 POST 提交到服务器),您可以将其包装在命名的 ngForm。这将确保其 Controller 不会覆盖范围内的父 Controller 。

    <div>
      <div ng-form name="customInput">
        <input type="text" ng-model="newInput" id="{{id}}" name="{{name}}">
      </div>
    </div>
    

    这可以在http://plnkr.co/edit/Jrk63A?p=preview处看到

  • 关于Angularjs 验证对于 1.3.0 和 1.2.6 的行为有所不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26439161/

    相关文章:

    javascript - Angular 内存游戏

    javascript - Angular 组件 : how to specified value for output binding function defined in parent?

    angularjs - 指令无权访问 Controller 功能(AngularJS)

    angularjs - 如果表单位于具有 ng-if 条件的 div 内,则无法读取未定义的属性 '$valid'

    angularjs - 使用来自 JSON 响应的有效 ng-click 操作构建 div

    javascript - Angular X-Editable 使可编辑字段出现在下一个表格单元格中

    angularjs - 为什么使用 $rollbackViewValue 时用于表单验证的 ng-messages 不起作用

    AngularJS 验证框架

    javascript - 从 angularJS 1.3-beta 迁移到 1.4 后 $http post 不工作

    angularjs - 如何始终启用 Angular 可编辑的编辑状态