由指令生成的输入字段表单验证

由指令生成的输入字段表单验证

本文介绍了Angularjs:由指令生成的输入字段表单验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经建立了生成基于元输入字段( $ scope.meta )数据的指令。
我的问题是支撑角度的表单验证。

I have built a directive that generates an input field based on meta ($scope.meta) data.My problem is supporting angular's Form validation.

Plunkr:

说明:指令需要一个参数,它描述了输入框的类型是和其他相关信息来渲染现场。在指令中定义的所有属性将被复制到元,最后编译和链接后,将取代指令。

Explanation: directive takes a meta parameter which describes what input field type it is and other related information to render the field. All the attributes defined on directive will be copied to element and finally will replace the directive after compilation and linking.

查看:

<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>

输入用户名或长或短于允许应该给我一个错误。
跳绳电子邮件字段显示我的错误了。

Entering username longer or shorter than allowed should show me an error.Skipping email field show me an error too.

下面是查看源 - code应用指令之后:

Here is the View source-code after applying the directive:

<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声明。

Here is the model the view and the directive working with, it's declared in ParentCtrl.

$scope.storage = {
    username: "Kitkat",
    email: "[email protected]"
};

这就是元数据信息,这告诉输入字段样子如何(这是一个文本?日期?等等。)

That's the meta information, this tell how the input field look like (is it a text? date? etc.)

 $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;
  });

一些想法:结果
每个指令创建一个孤立的范围,因此,该指令在窗体是看不见的,但是,存储(NG-模型)是绑定从指令的范围和父范围见过双向的,如果用户窗体所看到的是存储在应该是好的,不是吗?

Some thoughts:
Each directive creates an isolated scope, so, inside the directive userForm is unseen, however, the storage (ng-model) that is two-way binded is seen from directive's scope and parent scope, if userForm sees what's inside storage it should be ok, isn't it?

我试图通过窗体来指示范围:

I tried to pass userForm to directive scope:

// 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>

,但没有效果。

but with no effect.

当我看着指令范围,到窗体字段我看到输入字段实际上是 $脏:假 $无效:真正的,那之后,我键入的用户名/电子邮件领域,

When I look into the directives scope, into userForm field I see that the input field is actually $dirty: false, $invalid: true, and that after I typed into username/email field,

在源$ C ​​$ C这似乎验证类正确应用:
         NG-有效-MINLENGTH个 NG-脏 NG-无效 NG-无效,最大长度
尽管如此,没有验证错误显示。

In the source code it's seems that the validation classes are applied correctly: ng-valid-minlength ng-dirty ng-invalid ng-invalid-maxlengthstill, no validation errors are shown.

有什么我可以用它做什么?

Is there anything I can do with it?

推荐答案

为了对角的表单验证,以德能踢, ngModel 查找父 ngForm / 格式指令(在pre-链接阶段之前)。

In order for Angular's form-validation to de able to kick in, ngModel looks for a parent ngForm/form directive during its controller's instantiation phase (before the pre-linking phase).

由于编译并将其添加到DOM还有就是在那个时候没有父元素之前链接的元素,所以无法注册。

Since you compile and link the element before adding it to the DOM there is no parent element at that time, so it fails to register.

您只需要在第一个元素插入到DOM,然后编译和链接。

You just need to first insert the element into the DOM and then compile and link it.

Updated plunkr

这篇关于Angularjs:由指令生成的输入字段表单验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 10:22