2013-04-09 20 views
29

Tôi cố gắng tạo một chỉ thị cần thực hiện một số hành động khi trường nhập được đánh dấu là không hợp lệ. Ví dụ này cho phép giả sử tôi có một chỉ thị mà kiểm tra nếu đầu vào là một số nguyên tố, và tôi muốn tạo ra một chỉ thị mà thêm một lớp học để các phần tử khi nó không hợp lệ:Giá trị hiệu lực của chỉ thị AngularJS

<input type="text" ng-model="primeNumber" validate-prime invalid-add-class="error"> 

validate-thủ sử dụng phân tích cú pháp và định dạng trên mô hình ng để cập nhật tính hợp lệ của mô hình.

Bây giờ tôi muốn chỉ thị bổ sung không hợp lệ để thêm lớp "lỗi" khi mô hình không hợp lệ và xóa nó khi hợp lệ. Nói cách khác, nó sẽ xem thuộc tính $ valid (hoặc $ invalid) của bộ điều khiển mô hình. Tuy nhiên, tôi không thể tìm ra cách để làm việc này. Tôi cố gắng:

link : function(scope, element, attrs, ctrl) { 
    ctrl.$watch("$valid", function(newVal, oldVal) { 
    //never fired 
    }); 
} 

Có lẽ tôi có thể xem một số biến trên phạm vi, nhưng tôi không biết đó là biến để xem cho.

Vậy làm thế nào tôi có thể được thông báo khi hiệu lực của mô hình thay đổi?

+0

nếu bạn có thể chia sẻ chỉ thị của bạn, nó sẽ được tốt đẹp! –

+0

Tôi không nhớ những gì tôi đã sử dụng chính xác điều này, nhưng giải pháp thứ hai của CaioToOn là khá nhiều chức năng liên kết đã có. Chỉ nội dung của hàm thứ hai mới được lấp đầy với bất kỳ hành động nào bạn muốn khi hiệu lực thay đổi. – Tiddo

Trả lời

60

Nếu bạn có một <form>, hãy thêm name vào nó (cho phép giả định 'myForm') và name vào đầu vào của bạn (giả sử myInput). Bạn sẽ có thể $watch này bằng cách:

scope.$watch('myForm.myInput.$valid', function(validity) {}) 

Nếu bạn không có một form, bạn luôn có thể xem một hàm. Bằng cách này:

scope.$watch(function() { return ctrl.$valid; }, function(validity){}); 

Bạn có thể đọc thêm về cách tiếp cận biểu mẫu here.

+1

Cách tiếp cận thứ hai của bạn đã giúp tôi, cảm ơn! – Tiddo

7

Mục tiêu của chúng tôi, nói chung, nên làm cho một công việc chỉ thị độc lập với bất kỳ một hình thức hoặc đầu vào nào. Làm cách nào để chúng tôi có thể đọc được thuộc tính $valid cục bộ mà không ràng buộc nó với một biểu mẫu cụ thể duy nhất & tên đầu vào?

Chỉ cần sử dụng require: 'ngModel' làm một trong các thuộc tính của cấu hình chỉ thị của bạn. Điều này sẽ tiêm bộ điều khiển ngModel cục bộ làm đối số thứ tư cho hàm liên kết, và bạn có thể đặt số $watch trực tiếp trên $valid mà không cần phải thực hiện chỉ thị của từng chỉ thị cho bất kỳ biểu mẫu hoặc đầu vào cụ thể nào.

require: 'ngModel', 
link: function postLink(scope, element, attrs, controller) { 
    scope.inputCtrl = controller; 
    scope.$watch('inputCtrl.$valid', handlerFunc) 
} 

Trình xử lý phải nhất quán kích hoạt các thay đổi thành $ hợp lệ với cấu trúc đó. Xem this Fiddle, trong đó đầu vào được xác thực cho mẫu của Mã Zip hoặc Zip + 4 của Hoa Kỳ. Bạn sẽ nhận được cảnh báo mỗi lần thay đổi giá trị.

CHỈNH SỬA 3/21/14: Bài đăng này trước đây đã bị treo trên một ảo tưởng về tôi, khắc phục nguyên nhân sai của một vấn đề triển khai. Lỗi của tôi. Ví dụ trên loại bỏ sự cố định đó. Ngoài ra, thêm fiddle, cho thấy rằng phương pháp này thực tế làm việc, và luôn luôn làm, một khi bạn thêm dấu ngoặc kép xung quanh biểu thức xem.

+0

Bạn có chắc chắn rằng nó hoạt động không? Bởi vì với tôi có vẻ như 'inputCtrl. $ Valid' sẽ được đánh giá một lần (khi hàm liên kết được thực hiện) và kết quả được chuyển đến' scope. $ Watch'. Vì vậy, điều đó có nghĩa là cuộc gọi thực tế sẽ là 'phạm vi. $ Watch (true, handlerFunc)' hoặc 'scope. $ Watch (false, handlerFunc)', cả hai đều không dẫn đến một biến được theo dõi. – Tiddo

+0

'inputCtrl. $ Valid' là tham chiếu đến thuộc tính của đối tượng, không phải là giá trị nguyên thủy. Nó sẽ được đánh giá như vậy mỗi lần '$ watch' kích hoạt. Tôi đã có nó làm việc trên các dự án cá nhân, nhưng hiện tại không có một bản demo công khai tốt. – XML

+1

AFAIK 'inputCtrl. $ Valid' là nguyên thủy. Nó là 'true',' false' hoặc 'undefined', tất cả đều là nguyên thủy. Bạn không thể tạo tham chiếu đến các thuộc tính của đối tượng, chỉ với các đối tượng trong Javascript. Xem thêm JSFiddle này: http://jsfiddle.net/9Mh92/2/. Như bạn có thể thấy, mã của bạn không kích hoạt gọi lại, chỉ với dấu ngoặc kép. Điều này một lần nữa bởi vì bạn không thể tạo một tham chiếu đến bất kỳ nguyên thủy nào. Bằng cách đặt dấu ngoặc kép quanh 'inputCtrl. $ Valid', bạn hướng dẫn góc để đánh giá biểu thức đó trong phạm vi hiện tại và do đó nó hoạt động. – Tiddo

12

Nếu bạn không có một <form /> bạn có thể dễ dàng có được một:

Trong định nghĩa Chỉ thị của bạn:

require: '^form' 

và sau đó trong chức năng liên kết của bạn, hình thức được thông qua như là tham số thứ tư:

link: function (scope, element, attr, ctrl) { 

Bây giờ bạn không cần phải mã hóa cứng dạng hoặc lĩnh vực đầu vào để thực hiện các $ đồng hồ:

scope.$watch(ctrl.$name + '.' + element.attr('name') + '.$valid', 
function (validity) {}); 
+0

Điều này thật hoàn hảo. Mặc dù vì lý do nào đó, tôi đã phải sử dụng 'ctrl [0]. $ Name' - không chắc chắn tại sao điều khiển của tôi lại trả về một mảng gồm 1 biểu mẫu ... – DoubleA

+1

nó sẽ trả về một mảng nếu thuộc tính 'require' được truyền qua một mảng (Tôi nghi ngờ nó là dành cho bạn) – pixelbits

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