0

我有一個問題,控制器在頁面第一次加載和表單提交時觸發$ scope上定義的方法兩次。AngularJS:ngShow在控制器中觸發雙擊

這裏的小提琴: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模塊 - 先用控制器和其他用「的isValid」廠家服務

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); 

       } 

      } 

     } 

    }; 

}); 

而且 - 由於某種原因驗證只爲前兩個字段工作,似乎並沒有驗證空字段。

這裏就是我得到的控制檯時,第一次加載頁面(空數組),當表單第一次提交:

enter image description here

它似乎也呼籲與showWarning()方法在任何字段中鍵入內容時,每個'keydown'事件。

任何想法可能會導致它?

回答

1

validateEmptythis.isEmpty(...之前有假的!

至於他們爲什麼會被調用兩次,我猜你會提交一個摘要循環,而Angular正在檢查它的手錶以決定是否繼續顯示這些跨度,但我不完全確定爲什麼在這種情況下它是這樣做的。

+0

感謝您指出了這一點 - 代碼更新。 –

0

您未使用角度標準驗證。

這裏是一個非常CRUD電話自定義驗證

<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

+0

感謝Jorge,但由於某些原因,這些示例/演示似乎都不起作用 - 即使在文檔網站演示中也是如此? –