当指令动态创建表单输入时验证表单

时间:2014-12-13 22:37:44

标签: angularjs angularjs-directive

我正在尝试在使用指令时验证表单。该指令通过编译和替换元素来创建表单输入。

如果我使用指令的简单模板版本,它可以正常工作。如果指令创建的输入无效,则表示无效。它甚至可以在循环中创建时使用:http://codepen.io/kuasha/pen/gbreKP

 <div ng-app="app" ng-controller="MainCtrl">
    <form name="myform" ng-submit="sendForm()" novalidate>
        <div class="form-group">
            <myinput />
        </div>
        <div class="form-group">
            <button ng-show="myform.$valid" type="submit">Submit!</button>
        </div>
    </form>
</div>

应用和控制器:

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


app.controller('MainCtrl', function ($scope) {
    $scope.sendForm = function () {
        if ($scope.myform.$valid) {
            alert('form valid');
        }
    };
});        

以下是该指令的简单工作版本:

app.directive('myinput', function () {
        return {
            restrict: 'E',
            template: '<label>Test</label><input ng-model="value" type="text" required ng-minlength="5" />'
        };
    });

但是如果我更改指令以使用链接函数然后编译,即使指令内的输入无效,表单$ valid仍然为真:http://codepen.io/kuasha/pen/qEZoKv?editors=101

app.directive('myinput', function ($compile) {
    return {
        restrict: 'E',    
        link: function (scope, element, attributes) {
                var template = '<div><input type="text" required ng-minlength=5 /></div>'                               
                var newElement = angular.element(template);
                $compile(newElement)(scope);
                element.replaceWith(newElement);
            }                     

    };
});

编辑:

指令可以创建自己的验证器 -

app.directive('myinput', function ($compile) {
    return {
        require:'^form',
        restrict: 'E',
        scope: {
        },      
        controller: ['$scope', function($scope){

        }],
        link: function (scope, element, attributes, ctrl) {
                var template = '<label>Test</label><input name="myctrl" ng-model="value" type="text" required ng-minlength="5" />'                               
                var newElement = angular.element(template);
                $compile(newElement)(scope);
                element.replaceWith(newElement);

                scope.$watch("value", function(){
                  ctrl.$setValidity('myctrl', scope.value && scope.value.length > 0);
                  console.log("Validity set");
                });                        
            }                     

    };
});

但对于这个特殊问题,它可能不是正确的方法。

1 个答案:

答案 0 :(得分:0)

您应该切换replaceWith$compileDEMO):

element.replaceWith(newElement);
$compile(newElement)(scope);

我认为这是因为你无法真正编译一个尚未在DOM中的元素。但我不确定。