2013-06-09 33 views
9

Tôi có chỉ thị xác thực được gọi là valid-number được sử dụng để đặt hiệu lực của biểu mẫu bằng $ setValidity - điều này phù hợp với bất kỳ giá trị văn bản nào mà tôi nhập vào hộp nhập có chỉ thị được áp dụng cho như một thuộc tính.Xác thực biểu mẫu ban đầu bằng các chỉ thị

HTML là

<form name="numberForm"> 
<input name="amount" type="text" ng-model="amount" required valid-number /></form> 

Chỉ thị là như sau

angular.module('test',[]).directive('validNumber',function(){ 
      return{ 
       require: "ngModel", 
       link: function(scope, elm, attrs, ctrl){ 

        var regex=/\d/; 
        ctrl.$parsers.unshift(function(viewValue){ 
         var floatValue = parseFloat(viewValue); 

         if(regex.test(viewValue)){ 
          ctrl.$setValidity('validNumber',true); 
         } 
         else{ 
          ctrl.$setValidity('validNumber',false); 
         } 
         return viewValue; 
        }); 
       } 
      }; 
     }); 

Tuy nhiên, tôi cũng muốn xác nhận để được kích hoạt và thiết lập css đến một clsss không hợp lệ nếu giá trị đầu vào hộp được khởi tạo khi trang được tải đầu tiên không hợp lệ, ví dụ: nếu tôi đặt $scope.amount = 'not a number' Tôi mong đợi hộp nhập liệu đã có chỉ thị áp dụng cho nó, nhưng không có niềm vui. Để cho not a number được đánh dấu là không hợp lệ, tôi phải thực hiện thay đổi đối với nội dung của đầu vào, điều này sẽ kích hoạt chỉ thị.

Làm cách nào để đảm bảo chỉ thị áp dụng cho bất kỳ nội dung nào mà <input> được khởi tạo?

Ví dụ mã đầy đủ ở đây;

http://jsfiddle.net/JW43C/5/

Trả lời

16

$parsers mảng chứa một danh sách các chức năng sẽ được áp dụng với giá trị mô hình tiếp nhận từ chế độ xem (loại người dùng nào) và mảng $formatters chứa danh sách các hàm đang được áp dụng cho giá trị mô hình trước khi được hiển thị trong chế độ xem.

Trong chỉ thị của bạn, bạn sử dụng một cách chính xác các mảng $parsers, nhưng bạn cũng cần phải thêm mảng $formatters nếu bạn muốn giá trị ban đầu để được xác nhận:

angular.module('test',[]).directive('validNumber',function(){ 
    return{ 
    require: "ngModel", 
    link: function(scope, elm, attrs, ctrl){ 
     var regex = /^\d$/; 
     var validator = function(value){ 
     ctrl.$setValidity('validNumber', regex.test(value)); 
     return value; 
     }; 

     ctrl.$parsers.unshift(validator); 
     ctrl.$formatters.unshift(validator); 
    } 
    }; 
}); 

Demo plunker

+0

này làm việc tuyệt vời. – GrahamB

+1

Bài đăng tuyệt vời và nó làm nổi bật các chi tiết quan trọng như $ parsers và $ formatters khó tìm trong tài liệu. – Tobias

+0

Chỉ cần tham gia vào các trường hợp xác thực chéo phức tạp và bài đăng này đã lưu trong ngày - hoặc biến một ngày thành vài phút heh! – bchesley

1

Bạn chỉ có thể gọi chức năng xác minh của bạn trong giai đoạn liên kết, như trong fiddle này:

link: function(scope, elm, attrs, ctrl) {      
    var regex=/\d/; 
    var verificationFunction = function(viewValue) { 
     var floatValue = parseFloat(viewValue); 

     if(regex.test(viewValue)) { 
      ctrl.$setValidity('validNumber',true); 
      return viewValue; 
     } 
     else { 
      ctrl.$setValidity('validNumber',false); 
      return undefined; 
     } 
    }; 

    ctrl.$parsers.unshift(verificationFunction); 
    verificationFunction(); 
} 
0

Sau (> =) Phiên bản 1.3.1 góc đã được phát hành, bạn có thể thực hiện hành vi đó bằng một cách chính xác một chút, theo phong cách chỉ thị xác thực góc (ví dụ: required, maxlength).

Trong trường hợp đó bạn phải thêm validator của bạn như là tài sản của $validators mảng và không có nhu cầu ở $parsers hoặc $formatters nữa:

var app = angular.module('test', []); 
 

 
app 
 
    .directive('validNumber', function() { 
 
    return { 
 
     require: "ngModel", 
 
     link: function(scope, elm, attrs, ctrl) { 
 
     var regex = /^\d+$/; 
 

 
     ctrl.$validators['validNumber'] = function(modelValue, viewValue) { 
 
      return regex.test(viewValue); 
 
     }; 
 
     } 
 
    }; 
 
    }); 
 

 
app.controller('NumberCtrl', NumberCtrl); 
 

 
function NumberCtrl($scope) { 
 
    $scope.amount = '5z'; 
 
};
input.ng-invalid { 
 
    background-color: #FA787E; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script> 
 

 
<div ng-app="test"> 
 
    <div ng-controller="NumberCtrl"> 
 

 
    <div ng-form name="numberForm"> 
 
     <input name="amount" 
 
      type="text" 
 
      ng-model="amount" 
 
      required 
 
      valid-number /> 
 
     
 
     <span ng-show="numberForm.amount.$error.validNumber"> 
 
     Doesn't look like an integer 
 
     </span> 
 
    </div>   
 
    </div> 
 
</div>

Các vấn đề liên quan