如何创建用于表单验证的角度输入指令 [英] How to create a angular input directive that works with form validation

查看:15
本文介绍了如何创建用于表单验证的角度输入指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何创建一个 angular 指令,在表单中添加输入但也适用于表单验证.

How do I create an angular directive that adds a input in a form but also works with form validation.

例如下面的指令创建一个文本输入:

For instance the following directive creates a text input:

    var template = '\
<div class="control-group" ng-class="{ \'error\': {{formName}}[\'{{fieldName}}\'].$invalid}">\
    <label for="{{formName}}-{{fieldName}} class="control-label">{{label}}</label>\
    <div class="controls">\
        <input id="{{formName}}-{{fieldName}}" name="{{fieldName}}" type="text" ng-model="model" />\
    </div>\
</div>\
';

angular

    .module('common')

    .directive('formTextField', ['$compile', function ($compile) {
        return {
            replace: true,
            restrict: 'E',
            scope: {
                model: '=iwModel',
                formName: '@iwFormName',
                fieldName: '@iwFieldName',
                label: '@iwLabel'
            },
            transclude: false,
            template: template
        };
    }])

;

然而,输入并没有添加到表单变量 ($scope.formName) 中.我已经能够通过使用以下 stackoverflow 问题 Angularjs 中的 dynamicName 指令来解决这个问题: 表单验证和输入指令,但 ng-class 仍然不起作用.

However the input is not added to the form variable ($scope.formName). I've been able to work around that by using the dynamicName directive from the following stackoverflow question Angularjs: form validation and input directive but ng-class will still not work.

更新

它现在似乎可以工作了,但感觉就像是一个黑客.我以为我需要范围来获取表单和字段名称,但是我可以直接从属性中读取它.这样做会显示控制器范围表单变量中的字段.但是 ng-class 属性不适用.解决此问题的唯一方法是在范围可用后再次添加 html 元素.

It now seems to be working but it feels like a hack. I thought I needed the scope to grab the form and field names however I can read that directly from the attributes. Doing this shows the field in the controllers scope form variable. However the ng-class attribute does not apply. The only way around this is to add the html element a second time once the scope is available.

jsFiddle 这里

    var template = '\
<div class="control-group">\
    <label class="control-label"></label>\
    <div class="controls">\
        <input class="input-xlarge" type="text" />\
    </div>\
</div>\
';

angular

    .module('common')

    .directive('formTextField', ['$compile', function ($compile) {
        return {
            replace: true,
            restrict: 'E',
            scope: false,
            compile: function compile(tElement, tAttrs, transclude) {
                var elem = $(template);
                var formName = tAttrs.iwFormName;
                var fieldName = tAttrs.iwFieldName;
                var label = tAttrs.iwLabel;
                var model = tAttrs.iwModel;
                elem.attr('ng-class', '{ \'error\': ' + formName + '[\'' + fieldName + '\'].$invalid }');
                elem.find('label').attr('for', formName + '-' + fieldName);
                elem.find('label').html(label);
                elem.find('input').attr('id', formName + '-' + fieldName);
                elem.find('input').attr('name', fieldName);
                elem.find('input').attr('ng-model', model);

                // This one is required so that angular adds the input to the controllers form scope variable
                tElement.replaceWith(elem);

                return {
                    pre: function preLink(scope, iElement, iAttrs, controller) {
                        // This one is required for ng-class to apply correctly
                        elem.replaceWith($compile(elem)(scope));
                    }
                };

            }
        };
    }])

;

推荐答案

当我做这样的事情时,我使用指令 compile 函数在处理之前构建我的 html.例如:

when I do something like this, I use the directive compile function to build my html prior to it being processed. For example:

myApp.directive('specialInput', ['$compile', function($compile){
    return {
        // create child scope for control
        scope: true,
        compile: function(elem, attrs) {
            // use this area to build your desired dom object tree using angular.element (eg:)
            var input = angular.element('<input/>');

            // Once you have built and setup your html, replace the provided directive element
            elem.replaceWith(input);

            // Also note, that if you need the regular link function, 
            // you can return one from here like so (although optional)
            return function(scope, elem, attrs) {
                // do link function stuff here
            };
        }
    };
}]);

这篇关于如何创建用于表单验证的角度输入指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆