AngularJS:ngShow在控制器中触发双重

时间:2014-03-27 18:02:23

标签: angularjs angularjs-scope angularjs-service angularjs-controller ng-show

当页面首次加载时以及表单提交时,控制器触发$ scope上定义的方法时出现问题。

这里是小提琴:http://jsfiddle.net/scabro/pQb6q/5/

<div data-ng-app="app" data-ng-controller="AppCtrl">

<form method="post" data-ng-submit="submitForm()">

    <span data-ng-show="showWarning('email')">Please provide valid email address</span>
    <input type="email" name="email" placeholder="Email address" data-ng-model="fields.email.value" />

    <span data-ng-show="showWarning('telephone')">Please provide your telephone number</span>
    <input type="text" name="telephone" placeholder="Telephone" data-ng-model="fields.telephone.value" />

    <span data-ng-show="showWarning('name')">Please provide your name</span>
    <input type="text" name="name" placeholder="Name" data-ng-model="fields.name.value" />

    <button type="submit">Submit</button>

</form>

</div>

这里有两个AngularJs模块 - 第一个是控制器,另一个是&#39; isValid&#39;工厂服务

 angular.module('app', ['validation'])

.controller('AppCtrl', function($scope, $log, isValid) {

    $scope.fields = {

        email : {
            type : 'email',
            value : '',
            required : true
        },
        telephone : {
            type : 'number',
            value : '',
            required : true
        },
        name : {
            type : 'string',
            value : '',
            required : true
        }

    };

    $scope.warnings = [];

    $scope.showWarning = function(field) {

        $log.info($scope.warnings);

        return ($scope.warnings.indexOf(field) !== -1);

    };


    $scope.submitForm = function() {

        $scope.warnings = [];

        isValid.run($scope.fields);

        if (isValid.errors.length > 0) {

            $scope.warnings = isValid.errors;

        }

    };

});


 angular.module('validation', [])

.factory('isValid', function() {

    return {

        errors : [],

        isEmail : function(emailValue) {

          return (
              emailValue.indexOf("@") != -1
          );

        },

        isNumber : function(numberValue) {

            return (
                !isNaN(parseFloat(numberValue)) &&
                isFinite(numberValue)
            );

        },

        isEmpty : function(emptyValue) {

            return (
                emptyValue === '' ||
                emptyValue === 'undefined'
            );

        },

        validateEmail : function(fieldObject, fieldName) {

            if (!this.isEmail(fieldObject.value)) {

                this.errors.push(fieldName);

            }

        },

        validateNumber : function(fieldObject, fieldName) {

            if (!this.isNumber(fieldObject.value)) {

                this.errors.push(fieldName);

            }

        },

        validateEmpty : function(fieldObject, fieldName) {

            if (this.isEmpty(fieldObject.value)) {

                this.errors.push(fieldName);

            }

        },

        type : function(fieldObject, fieldName) {

            switch(fieldObject.type) {

                case 'email':
                    if (fieldObject.required || !this.isEmpty(fieldObject.value)) {
                        this.validateEmail(fieldObject, fieldName);
                    }
                    break;

                case 'number':
                    if (fieldObject.required || !this.isEmpty(fieldObject.value)) {
                        this.validateNumber(fieldObject, fieldName);
                    }
                    break;

                default:
                    if (fieldObject.required) {
                        this.validateEmpty(fieldObject, fieldName);
                    }
                    break;

            }

        },

        resetErrors : function() {

            this.errors = [];

        },

        run : function(fields) {

            this.resetErrors();

            for (var fieldName in fields) {

                if (fields.hasOwnProperty(fieldName)) {

                    this.type(fields[fieldName], fieldName);

                }

            }

        }

    };

});

此外 - 由于某种原因,验证仅适用于前2个字段,并且似乎无法验证空字段。

这是我在首次加载页面(空数组)时以及首次提交表单时我在控制台中获得的内容:

enter image description here

它似乎也在调用每个&#39; keydown&#39;的showWarning()方法。在任何字段内输入时的事件。

知道可能导致它的原因吗?

2 个答案:

答案 0 :(得分:1)

validateEmpty!之前有一个虚假的this.isEmpty(...

至于为什么他们两次被叫,我猜你提交的时候正在运行一个摘要周期,而Angular正在检查它的手表以决定是否继续显示这些跨度,但是我&#39;我不完全确定为什么它会在这种情况下这样做。

答案 1 :(得分:0)

您没有使用角度标准验证。

这是一个非常粗暴的电话自定义验证的例子

<div data-ng-app="app" data-ng-controller="AppCtrl">
  <form method="post" name="form" data-ng-submit="submitForm()">

    <input required="" type="email" name="email" placeholder="Email address" data-ng-model="fields.email.value" />
    <div data-ng-show="form.email.$dirty && form.email.$invalid">Please provide valid email address</div>
    <br />
    <input required="" valid-telephone type="text" name="telephone" placeholder="Telephone" data-ng-model="fields.telephone.value" />
    <div data-ng-show="form.telephone.$dirty && form.telephone.$invalid">Please provide your telephone number</div>
    <br />
    <input required="" type="text" name="name" placeholder="Name" data-ng-model="fields.name.value" />
    <div data-ng-show="form.name.$dirty && form.name.$invalid">Please provide your name</div>
    <br />
    <button type="submit">Submit</button>
  </form>
</div>

angular.module('app', [])

.controller('AppCtrl', function($scope, $log) {
    $scope.fields = {
        email : {
            value : ''
        },
        telephone : {
            value : ''
        },
        name : {
            value : ''
        }
    };
    $scope.submitForm = function() {

    };

})
.directive('validTelephone', [function() {
  return {
    require: 'ngModel',
    link: function(scope, ele, attrs, c) {
      scope.$watch(attrs.ngModel, function() {
          c.$setValidity('unique', /^\d{10}$/.test(c.$viewValue));
      });
    }
  };
}]);

input.ng-invalid {
  border: 1px solid red;
}

input.ng-valid {
  border: 1px solid green;
}

这是代码

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

这里有一些文档

http://scotch.io/tutorials/javascript/angularjs-form-validation