在指令中访问子项的“$invalid”验证道具

Accessing child's '$invalid' validation prop within a directive

我正在尝试创建一个可重复使用的指令,该指令将根据其中一个子元素的 $invalid 属性 简单地向元素添加 class。

我开始创建指令,但不确定如何访问 $invalid 道具:


简化标记:

<form>
    <div class="group" ng-validate="emailAddress">
        <div class="wrapper">
            <input type="email" name="emailAddress" ng-model="emailAddress" required/>
        </div>
    </div>
</form>


和指令:

function ngValidate ()
{
    function linkFunction (scope, element, attributes, controller)
    {
        var el = element[0];
        var targetElName = attributes.ngValidate;
        var $targetEl = angular.element(el.querySelector("[name='" + targetElName + "']"));

        $targetEl.on("blur", blurHandler);

        function blurHandler (event)
        {
            console.log($targetEl.$invalid); // always undefined??

            // what I want to happen (sudo code):

            // if $targetEl is $invalid then add class 'error' to element.
            // if $targetEl is $valid then add class 'success' to element.
        }
    }

    return {
        restrict: "A",
        link: linkFunction
    };
}


我对此有点困惑,所以任何帮助将不胜感激。

试试这个:

<form name="myform">
    <div class="group" ng-validate="emailAddress">
        <div class="wrapper">
            <input type="email" name="emailAddress" ng-model="emailAddress" ng-class="{ 'bademail' : myform.email.$invalid }" required/>
        </div>
    </div> </form>

您也可以只在 CSS 中指定 .group input[type=email] .ng-invalid { color: red; }(ng-invalid 会自动添加为 class)。

有关所有 FormController 属性的更多信息:

https://docs.angularjs.org/api/ng/type/form.FormController

  1. Angular 有内置的电子邮件验证器。您可以使用 formName.fieldName.$error.email 检查它是否有效。但是如果你只是弄清楚基本的验证概念呢。
  2. 您将指令应用于 div,但我认为您必须将其应用于输入
  3. 您必须使用 ngModel $validators$parsers 进行广告验证。因为 $invalid 是一个只有 ngModel
  4. 的 属性 元素

```

<form name="myForm">
    <div class="group">
        <div class="wrapper">
            <input type="email" ng-validate="emailAddress" name="emailAddress" ng-model="emailAddress" required/>
            <div class="error" ng-show="myForm.emailAddress.$error.myemail" >Email is not correct</div>
        </div>
    </div>
</form>

```

现在创建验证指令。

function ngValidate ()
{
    function linkFunction (scope, element, attributes, controller)
    {
        controller.$parsers.push(function(value){
            if(!value || value.length == 0) return;

            controller.$setValidity('myemail', true);

            switch(scope.ngValidate) {
                case 'emailAddress':
                    if(!value.match(/email regex/g)) {
                        controller.$setValidity('myemail', false);
                    }
                break;
            }
        });
    }

    return {
        restrict: "A",
        require: 'ngModel',
        scope: {
            'ngValidate': '@'
        },
        link: linkFunction
    };
}

有了这个你也可以使用 ngMessages.

一般来说,我建议在 google 中搜索 Angularjs 验证。你可以在那里学到很多东西。

更新

如果您只想根据字段验证将 class 添加到包装器。

<div class="group" ng-class="myClass(myForm, 'emailAddress')">

现在在控制器中

$scope.myClass = function(form, name) {
    var error = !angular.equals({}, form[name].$error);

    if(form[name].$dirty && !error) {
        return 'has-success'
    }
    if((form[name].$dirty || form.$submitted) && error) {
        return 'has-error'
    }
}

如果字段中至少有一个错误,这将添加 class has-error,如果 none.

,则添加 has-success

感谢@Ghan 建议使用 class 名称,我现在创建了一个工作指令来封装逻辑:

示例标记(将值更改为 'surname' 以避免混淆):

<form>
    <div class="group" ng-validate="surname">
        <div class="wrapper">
            <input type="text" name="surname" ng-model="surname" required/>
        </div>
    </div>
</form>


工作指示:

function ngValidate ()
{
    function linkFunction (scope, element, attributes, controller)
    {
        var el = element[0]; // grab the DOM element from the angular/jQuery element.
        var targetElName = attributes.ngValidate;
        var $targetEl = angular.element(el.querySelector("[name='" + targetElName + "']"));

        $targetEl.on("blur", blurHandler);

        function blurHandler (event)
        {
            if ($targetEl.hasClass("ng-invalid"))
            {
                // add remove success class and error class.
                element.removeClass("form-controlGroup--success").addClass("form-controlGroup--error");
            }
            else if ($targetEl.hasClass("ng-valid"))
            {
                // add remove error class and success class.
                element.removeClass("form-controlGroup--error").addClass("form-controlGroup--success");
            }
        }
    }

    return {
        restrict: "A",
        link: linkFunction
    };
}