AngularJS表单验证 - formName。$ valid始终为true

时间:2016-09-26 09:35:54

标签: javascript angularjs angularjs-directive

我有一个简单的表单,其中的字段是通过名为field的指令动态生成的。当我点击提交时,字段会经过验证并生成有效的类名,例如ng-invalidng-invalid-email。但表单的类名始终为ng-valid。任何帮助将不胜感激!

Plnkr

HTML

<body ng-controller="app_controller">
    <form name="register" ng-submit="register_user()" novalidate>
      <table>
        <tr>
          <td>Username: </td>
          <td><field name="username" value="info"></field></td>
        </tr>
        <tr>
          <td>Email: </td>
          <td><field name="email" value="info"></field></td>
        </tr>
        <tr>
          <td></td>
          <td><input type="submit" value="submit" ng-disabled="register.$invalid" /></td>
        </tr>
      </table>

      Invalid: {{ register.$invalid }} <br />
      valid: {{ register.$valid }}
    </form>

JS

var app = angular.module('app', []);

app.controller('app_controller', function($rootScope, $scope) {
  $scope.info = {
    username: '',
    email: ''
  };

  $rootScope.meta = {
    "username": {
      type: "STRING",
      length: 255
    },
    "email": {
      type: "EMAIL",
      length: 255
    }
  };
});

app.directive('field', function($rootScope, $compile) {
  return {
    restrict: 'E',
    scope: {
      value: '='
    },
    link: function($scope, $element, $attrs) {
      $scope.field_name = $attrs.name;
      $scope.required = true;
      console.log($scope);
      var prepare_fields = function() {
        if ($rootScope.meta) {
          $scope.field = angular.copy($rootScope.meta[$attrs.name]);
        }

        var html = '';
        if ($scope.field.type === "STRING") {
          html = '<input type="text" name="' +$scope.field_name+ '" ng-model="value[field_name]" ng-required="required" />';
        } else if ($scope.field.type === "EMAIL") {
          html = '<input type="email" name="' +$scope.field_name+ '" ng-model="value[field_name]" ng-required="required" />';
        }

        $element.html($compile(html)($scope));
      };

      $rootScope.$watch('meta', prepare_fields);
    }
  }
});

1 个答案:

答案 0 :(得分:1)

添加内容后

编译element.contents,所以只需添加两行

$element.html(html);
$compile($element.contents())($scope);

而不是

$element.html($compile(html)($scope));

应该有效:)

指令中的最终代码:

var html = '';
if ($scope.field.type === "STRING") {
    html = '<input type="text" name="' +$scope.field_name+ '" ng-model="value[field_name]" ng-required="required" />';
} else if ($scope.field.type === "EMAIL") {
    html = '<input type="email" name="' +$scope.field_name+ '" ng-model="value[field_name]" ng-required="required" />';
}

// $element.html($compile(html)($scope));
$element.html(html);
$compile($element.contents())($scope);

N.B:问题是您编译了字符串而不是元素html 。因此,在修改元素之后编译元素内容时,它就会正常工作。