ng-class不在表单验证的指令内工作

时间:2015-02-05 16:32:44

标签: angularjs

我有一个表单,里面有一个这样的指令: addEditUser.html:

    <form role="form" class="form-horizontal" novalidate name="addEditUserForm" >
        <div class="form-group labelInputContainer">
            <label for="emailAddr" class="col-xs-1 col-sm-1 col-md-1 control-label">E-mail</label>
            <div class="col-xs-8 col-sm-8 col-md-8">
                <input type="text" ng-class="{'invalid': addEditUserForm.emailAddr.$error.required}" maxlength="100" class="form-control" id="emailAddr" name="emailAddr" placeholder="E-mail" ng-model="user.emailAddr" required />
            </div>
        </div>
        <address default-addr="defaultAddr" />
        <button type="submit" class="btn greenButton" style="width: 100%;" ng-click="saveUser();" data-ng-disabled="addEditUserForm.$invalid">SAVE</button>
    </form>

addEditUserController.js

    app.controller('addEditUserController', function ($scope, $routeParams, $location, $filter, reposSvc) {
         $scope.defaultAddr = {};
         var id = $routeParams.id;
         if (id) {
             $scope.user = reposSvc.user.get({ id: id },
                function (data) {
                    $scope.defaultAddr = data.defaultAddr;
              });
    });

指令HTML(address.html):

<div>
    <div class="form-group labelInputContainer">
        <label for="streetAddress" class="col-xs-2 col-sm-2 col-md-2 control-label">Street</label>
        <div class="col-xs-3 col-sm-3 col-md-3">
            <input type="text" ng-class="{'invalid': addEditUserForm.streetAddress.$error.required}" maxlength="100" class="form-control noLimitsTextBox" id="streetAddress" name="streetAddress" ng-model="defaultAddr.streetAddress" placeholder="Street" required />
        </div>
        <label for="no" class="col-xs-2 col-sm-2 col-md-2 control-label">No</label>
        <div class="col-xs-3 col-sm-3 col-md-3">
            <input type="text" maxlength="6" class="form-control" id="no" name="no" placeholder="No" />
        </div>
    </div>
</div>

address.js:

(function () {
    'use strict';

    app.directive('address', function () {
        return {
            restrict: 'E',
            replace: true,
            templateUrl: 'app/directives/address.html',
            scope: {
                defaultAddr: '='
            },
            controller: function ($scope, reposSvc, toastr) {

            }
        };
    });
})();

按钮被禁用,直到我填写所有必填字段(在此简短示例中为电子邮件和街道)。但只有电子邮件才会应用“无效”类(背景颜色)。所以主要是验证适用于两个控件,但ng-class仅适用于主html中的电子邮件字段。 我究竟做错了什么?如何从指令控件上应用ng-class获得“无效”类?

1 个答案:

答案 0 :(得分:1)

原因是因为您的指令是隔离的作用域(它不会自动从父级继承),因此它不会将具有属性名称的特殊表单对象作为属性添加到作用域上。因此,您需要将其作为双向绑定传递,或者使用$parent.addEditUserForm来访问它虽然看起来很糟糕(影响可重用性),或者只是使用scope:true但它可能无法满足您的目的使用孤立范围的意图。验证有效,因为你的ng-model是双向绑定属性ng-model="defaultAddr.streetAddress",它仍然附加到formcontroller实例。

所以你可以这样做:

return {
        restrict: 'E',
        replace: true,
        templateUrl: 'app/directives/address.html',
        scope: {
            defaultAddr: '=',
            form:'=' //<-- Add a binding
        },
        controller: function ($scope, reposSvc, toastr) {

        }
    };

  <input type="text" ng-class="{'invalid': form.streetAddress.$error.required}" maxlength="100" class="form-control noLimitsTextBox" id="streetAddress" name="streetAddress" ng-model="defaultAddr.streetAddress" placeholder="Street" required />

并将其传递给:

 <address default-addr="defaultAddr" form="addEditUserForm" />

注意:我在双向绑定中使用了名称form,因此它没有与特定表单名称紧密耦合,而且更可重用。

或者作为其他选项而不是使用ng-class设置类只需使用元素在无效时添加的ng-invalidng-invalid-required等类。