【问题标题】:Angularjs: Form validation on input field generated by directiveAngularjs:对指令生成的输入字段进行表单验证
【发布时间】:2014-10-11 13:04:46
【问题描述】:

我已经构建了一个指令,该指令根据元 ($scope.meta) 数据生成输入字段。 我的问题是支持 Angular 的表单验证。

Plunkr:http://plnkr.co/edit/AfR5cWyywGlCECS6h6Dr?p=preview

说明:指令采用meta 参数,该参数描述了它是什么输入字段类型以及呈现该字段的其他相关信息。指令上定义的所有属性都会被复制到元素中,最后在编译链接后替换指令。

查看:

<form name="userForm">
    <!-- Username -->
    <poly-field ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field>
    <p ng-show="userForm.username.$error.minlength" class="help-block">Username is too short.</p>
    <p ng-show="userForm.username.$error.maxlength" class="help-block">Username too long</p>

    <!-- Email -->
    <poly-field ng-model="storage" meta="meta" key="email" name="email" ng-required></poly-field>
    <p ng-show="userForm.email.$error.minlength" class="help-block">Email is too short.</p>
    <p ng-show="userForm.email.$error.maxlength" class="help-block">Email is too long</p>
</form>

输入的用户名比允许的长或短应该会显示一个错误。 跳过电子邮件字段也会显示错误。

这是应用指令后的查看源代码:

<form name="userForm" class="ng-pristine ng-valid ng-valid-required">
        <!-- Username -->
        <input type="undefined" ng-model="storage.username" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8" class="ng-scope ng-valid-minlength ng-dirty ng-valid ng-valid-maxlength">
        <p ng-show="userForm.username.$error.minlength" class="help-block ng-hide">Username is too short.</p>
        <p ng-show="userForm.username.$error.maxlength" class="help-block ng-hide">Username too long</p>

        <!-- Email -->
        <input type="undefined" ng-model="storage.email" meta="meta" key="email" name="email" ng-required="" class="ng-scope ng-valid ng-valid-required ng-dirty">
        <p ng-show="userForm.email.$error.minlength" class="help-block ng-hide">Email is too short.</p>
        <p ng-show="userForm.email.$error.maxlength" class="help-block ng-hide">Email is too long</p>
</form>

这是视图和指令使用的模型,它在 ParentCtrl 中声明。

$scope.storage = {
    username: "Kitkat",
    email: "flying@kitkat.com"
};

这是元信息,它告诉输入字段的样子(是文本吗?日期?等等)

 $scope.meta = {
    username: { type: "text" },
    email: { type: "text" }
};

指令声明:

app.directive('polyField', function($compile) {
    var linkFn = function(scope, element, attributes) {
        // create input element depending on the type
        var template = document.createElement("input");
        template.type = scope.storage[attributes.key].type;

        // copy all attributes
        for (var attr in attributes.$attr) {
            if (attributes.$attr[attr] == 'ng-model') {
                template.setAttribute('ng-model', attributes[attr] + '.' + attributes.key);
            } else {
                template.setAttribute(attributes.$attr[attr], attributes[attr]);
            }
        }

        // template compilation, linking and element replacement
        template = angular.element(template.outerHTML);
        var linkTemplate = $compile(template);
        var domElement = linkTemplate(scope);
        element.replaceWith(domElement);
    }

    var directive = {
        restrict: 'E',
        scope: { 
            meta: '=',
            storage: '=ngModel',
            key: '=',
        },
        link: linkFn
    };

    return directive;
  });

一些想法:
每个指令都会创建一个隔离范围,因此,在指令 userForm 内部是看不见的,但是,如果 userForm 看到 @ 内部的内容,则可以从指令的范围和父范围看到双向绑定的 storage(ng-model) 987654331@应该没问题吧?

我试图将userForm 传递给指令范围:

// directive
scope: {
        meta: '=',
        storage: '=ngModel',
        key: '=',
        userForm: '='
}

// template
<poly-field user-form="userForm" ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field>

但没有效果。

当我查看指令范围时,进入userForm 字段我看到输入字段实际上是$dirty: false$invalid: true,并且在我输入用户名/电子邮件字段之后,

在源代码中,验证类似乎已正确应用: ng-valid-minlength ng-dirty ng-invalid ng-invalid-maxlength 仍然没有显示验证错误。

我能用它做些什么吗?

【问题讨论】:

    标签: angularjs validation directive


    【解决方案1】:

    为了使 Angular 的表单验证能够启动,ngModel 在其控制器的实例化阶段(预链接阶段之前)寻找父 ngForm/form 指令。

    由于在添加到 DOM 之前已经编译并链接了元素,因此当时没有父元素,因此无法注册。

    你只需要先将元素插入到 DOM 中,然后编译链接即可。

    Updated plunkr

    【讨论】:

      猜你喜欢
      • 2014-08-02
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多