Tự thiết kế directives trong angularjs
Giới thiệu AngularJS đã hỗ trợ sẵn rất nhiều directives như ng-app (khởi tạo một AngularJS application), ng-init (khởi tạo dữ liệu), ng-repeat (lặp các phần tử HTML)... Tuy nhiên những directive ấy vẫn không đủ để hỗ trợ các lập trình viên. Vì vậy AngularJS cho phép các lập trình viên tự thiết kế ...
Giới thiệu
AngularJS đã hỗ trợ sẵn rất nhiều directives như ng-app (khởi tạo một AngularJS application), ng-init (khởi tạo dữ liệu), ng-repeat (lặp các phần tử HTML)... Tuy nhiên những directive ấy vẫn không đủ để hỗ trợ các lập trình viên. Vì vậy AngularJS cho phép các lập trình viên tự thiết kế những directive phục vụ những mục đích riêng của mình.
ng-messages
ng-messages là một directive để validate form ngoài view cho client. Chi tiết các bạn có thể tìm hiểu tại đây: https://viblo.asia/nminhduc/posts/WrJeYEodeVO
Hiện tại ng-messages chỉ hỗ trợ 3 dạng validate là ng-required, ng-maxlength/minlength và ng-pattern.
- ng-required để validate form bắt buộc phải được nhập. Nếu form đó bị bỏ trống thì sẽ báo lỗi
- ng-maxlength/minlength để validate số lượng ký tự tối đa và tối thiểu của forrm
- ng-pattern để validate form theo một định dạng có sẵn bằng regex
Vì chỉ có 3 dạng validate cơ bản như trên nên trong nhiều trường hợp ta không sử dụng được ng-messages.
Để khắc phục vấn đề trên, ta viết thêm directive để hỗ trợ những kiểu validate khác nhau.
Custom directive formatDate
Giả sử ta muốn validate một form định dạng datetime, nằm trong khoảng từ năm 1000 đến năm 9999. Ta viết thêm một directive như sau:
angular.module('registerApp').directive('date', date); function date() { return { require: 'ngModel', link: function(scope, element, attributes, ngModel) { var modelValuePresent = function (modelValue) { return modelValue !== null && modelValue !== ' && !_.isUndefined(modelValue); } ngModel.$validators.formatDate = function(modelValue) { if (modelValuePresent(modelValue)) { var year = modelValue.getFullYear(); return year >= 1000 && year <= 9999; } return true; }; attributes.$observe('date', function() { ngModel.$validate(); }); } }; };
Directive này có tên date, được sử dụng tương tự như ng-requied. chỉ cần đặt date vào trong form mình muốn validate.
<input type="date" ng-model="model" required date />
Đầu tiên directive sẽ kiểm tra xem form đã có giá trị hay chưa bằng hàm modelValuePresent, nếu chưa có thì bỏ qua, không tiếp tục so sánh. Nếu đã có giá trị hợp lệ, directive sẽ kiểm tra format của giá trị trong form bằng hàm validate formatDate.
Nếu giá trị của form hợp lệ thì directive trả về true còn không sẽ trả về false cho quá trình validate này.
Lúc này ng-messages sẽ nhận kết quả của directive validate date trong một key cũng tên là date. Khi form không thỏa mãn format thì key date sẽ được add vào $$rror để cho ta dễ dàng nhận biết.
<div ng-message="date">Wrong format</div>
Custom directive compareDate
Còn trong trường hợp ta muốn so sánh form datetime ấy với một giá trị datetime khác. Ta sử dụng directive sau:
angular.module('registerApp').directive('date', date); function date() { return { require: 'ngModel', link: function(scope, element, attributes, ngModel) { var modelValuePresent = function (modelValue) { return modelValue !== null && modelValue !== ' && !_.isUndefined(modelValue); } ngModel.$validators.compareDate = function(modelValue) { if (modelValuePresent(modelValue)) { return modelValue >= new Date(attributes.compareDate.slice(1, -1)); } return true; }; attributes.$observe('date', function() { ngModel.$validate(); }); } }; };
Sử dụng directive này có khác đôi chút so với directive phía trên vì có thêm đối tượng so sánh được truyền thêm vào. Cũng khá giống khi khai báo ng-maxlength
<input type="date" ng-model="model" required date="anyDatetime" />
Cách validate cũng giống bên trên. Chỉ khác là ta cần lấy ra đối tượng được truyền vào và so sánh với giá trị của form.
Trên đây tôi đã giới thiệu với các bạn một số case validate với form datetime bằng cách viết thêm các directive.