角度自定义表单验证$ error无效

时间:2014-02-04 12:04:31

标签: angularjs angularjs-directive

这是你撕裂头发的那些虫子之一。

我已经编写了一个指令,根据在选择框中选择的值,对时间,距离或点数进行自定义验证。这里工作得很好:

http://plnkr.co/edit/FECdILYtahR0HjoWysTr?p=preview

当我将指令应用于我的应用程序时,问题就开始了。表单的$ invalid属性设置为true,但$ error.mymeasure虽然在调试器中显然设置为true,但对视图没有任何影响。

Chrome调试器输出屏幕截图:http://prntscr.com/2peomt

输出$ error和$ invalid属性的代码:

entriesForm.savedcurvalue.$error.mymeasure: {{ entriesForm.savedcurvalue.$error.mymeasure }} 
  / $invalid: {{ entriesForm.$invalid }} <br/>

视图中的实际输出:

entriesForm.savedcurvalue.$error.mymeasure: / $invalid: true

据我所知,相关代码与测试相同...这里是html :(带指令的输入位于底部)

<form name="entriesForm" class="css-form" novalidate>
<div class="grey-border" ng-show="entriesData.currentAthleteIndex != undefined">

<!--********  ALREADY SAVED ********-->
<div ng-show="entriesData.showEventListGroup=='saved'">
    <ul class="inline entry-table-head">
        <li class="entry-col-1">{{ 'entries.class' | i18n }}</li>
        <li class="entry-col-2">{{ 'entries.event.curValue' | i18n }}</li>
        <li class="entry-col-3">{{ 'entries.event.curWeightHeight' | i18n }}</li>
        <li class="entry-col-4">{{ 'entries.event.datDate' | i18n }}</li>
        <li class="entry-col-5">{{ 'entries.event.strTown' | i18n }}</li>
        <li class="entry-col-6">{{ 'entries.event.bolindoor' | i18n }}</li>
    </ul>
    <span ng-show="entriesForm.measurement.$error.measure">{{ measurementFormat }} </span>
    entriesForm.savedcurvalue.$error.mymeasure: {{ entriesForm.savedcurvalue.$error.mymeasure }} / $invalid: {{ entriesForm.$invalid }} <br/>
    <ul class="unstyled">
        <li ng-repeat="event in currentEditItem.athleteList[entriesData.currentAthleteIndex].events"
            ng-show="event.selected && !event.isRelay">

            <ul class="inline">
                <li class="entry-col-1"
                    ng-class="{requestStatusGreen:event.ownEvents && event.ownSex, requestStatusYellow:!event.ownEvents && event.ownSex, requestStatusRed:!event.ownEvents && !event.ownSex}">
                    <label class="checkbox inline">
                        <input type="checkbox" ng-model="event.selected" ng-click="setIntStateSave(event,currentEditItem.athleteList[entriesData.currentAthleteIndex])"/>
                        {{ event.strIdClass }} - {{ event.strName }}
                    </label>
                </li>
                <li class="entry-col-2 control-group" ng-class="{error:entriesForm.saved_curValue.$error.measure}">
                    <input class="input-mini" type="text" ng-model="event.curValue" ng-change="setChecked(event)" name="savedcurvalue"
                           smart-measurement="event.intType" errorformat="measurementFormat" decimal="DECIMAL" />
                </li>

指令:

app.directive('smartMeasurement', function () {
    return {
        require: 'ngModel',
        scope: {
            ngModel: '=',
            smartMeasurement: '=',
            errorformat: '=',
            decimal: '='
        },
        link: function (scope, elm, attrs, ctrl) {
            var REGEX;
            var TIME_REGEXP;
            var LENGTH_REGEXP;
            var MULTI_REGEXP = /^(?:\d{1,5})?$/;

            if (scope.decimal == ",") {
                TIME_REGEXP = /^(?:\d+:)?(?:[0-5]\d:|[0-9]:)?(?:[0-5]\d|\d|^\d\d\d)(?:[.,]\d\d?)?$/;
                LENGTH_REGEXP = /^(?:\d{1,3})(?:[,]\d)(\d)?$/;
            } else {
                TIME_REGEXP = /^(?:\d+:)?(?:[0-5]\d:|[0-9]:)?(?:[0-5]\d|\d|^\d\d\d)(?:[.,]\d\d?)?$/;
                LENGTH_REGEXP = /^(?:\d{1,3})(?:[.]\d)(\d)?$/;
            }

            ctrl.$parsers.unshift(function (viewValue) {
                switch (scope.smartMeasurement) {
                    case 3:
                        REGEX = LENGTH_REGEXP;
                        scope.errorformat = "00" + scope.decimal + "00";
                        break;
                    case 4:
                        REGEX = MULTI_REGEXP;
                        scope.errorformat = "00000";
                        break;
                    default:
                        REGEX = TIME_REGEXP;
                        scope.errorformat = "[hh:mm:]ss" + scope.decimal + "t[h] / [s]ss" + scope.decimal + "t[h]";
                        break;
                }
                if (REGEX.test(viewValue)) {
                    ctrl.$setValidity('mymeasure', true);
                    return viewValue;
                } else {
                    ctrl.$setValidity('mymeasure', false);
                    return undefined;
                }
            });
        }
    };
});

我正在使用Angular 1.06 - 该项目大约在一年前启动,所以目前升级到1.2并不是一个真正的选择。我想也许依赖关系中的一个可能阻止它工作。我会测试这个,虽然我发现它不太可能。但这是我唯一能想到的可能是错误的。

如果有人可能会出现错误或建议我应该看一个地方,那将非常感激。

1 个答案:

答案 0 :(得分:1)

好的,我发现了问题。我在循环中有表单字段,这意味着名称字段不明显。

答案是在循环的每次迭代中添加ng-form,然后检查此表单的每个字段的错误状态...

<form name="form" class="form-horizontal" novalidate>
    form.measurement.$error.measure: {{ form.measurement.$error.measure }} <br/>

    <div class="alert alert-error" ng-show="form.measurement.$error.measure">
        {{ measurementFormat }}
    </div>
    <ul class="unstyled">
        <li class='control-group' ng-class="{error:form.measurement.$error.measure}" ng-repeat="l in loop">
            <ng-form name="loopForm">
                loopForm.measurement.$error.measure: {{ loopForm.measurement.$error.measure }} <br/>
                <input class="input-mini error" type="text" ng-model="measurement" ng-change="setChecked()"
                       name="measurement" smart-measurement=selectedFormat errorformat="measurementFormat" decimal="DECIMAL"/>
                {{measurement}}
            </ng-form>
        </li>
    </ul>
</form>

我希望这有时可以帮助某人: - )