Bài 07: Directive ng-model-options trong AngularJS
Bài trước chúng ta đã tìm hiểu một Directive rất quan trọng đó là ng-model trong AngularJS, và chúng ta cũng làm được khá nhiều ví dụ cho chủ đề ng-model này. Vậy để tiếp tục theo luồng serie thì trong bài này chúng ta sẽ tìm hiểu một Directive khác có liên quan mật thiết đến ng-model đó là ng-model-options trong AngularJS.
Tôi cũng xin nhắc lại nếu bạn là người mới tìm hiểu thì nên đọc kỹ những nội dung mà tôi viết chứ đừng coi ví dụ không thôi, như vậy bạn sẽ không hiểu được ý đồ của mình đâu.
1. ng-model-options là gì?
Dịch cái tên ra cũng đủ hiểu ý nghĩa của nó rồi, chúng ta thường sử dụng Directive ngModelOptions dùng để cấu hình một số thông số liên quan tới ng-model. Khi ứng dụng được chạy lên thì Directive này sẽ thực thi trước và sau đó ng-model mới được tạo.
Những thông số cấu hình này sẽ quyết định đến giá trị của model có được thay đổi và lưu vào $scope hay không? Nếu như lưu thì khi nào lưu? và cách lưu như thế nào? Tất cả những câu hỏi này chính là những ngModelOptions trong angular đấy;
Bài viết này được đăng tại [free tuts .net]
2. Tìm hiểu $rollbackViewValue
Như các bạn thấy mỗi khi dữ liệu thay đổi thì sẽ được lưu vào trong $scope nên những thuộc tính nào đang được liên kết (ng-bind) với nó sẽ thay đổi theo, nhưng có những trường hợp ta muốn người dùng nhập nhưng không thay đổi nó trong $scope và ta cần lấy giá trị nguyên thủy này thì phải làm thế nào? Rất đơn giản, $roolbackViewValue sẽ giải quyết vấn đề này cho bạn. Vậy $rollbackViewValue chính là giá trị hiện tại của các thẻ input (model) được lưu trong mô hình của chúng ta.
Để gọi tới một view (giá trị thẻ input có khai báo model) nào đó trong form ta sẽ dùng cú pháp như sau trong controller:
$scope.formName.inputName.$rollbackViewValue;
3. Các tham số của ng-model-options trong AngularJS
Các thông số options dưới đây sẽ được gắn vào Model hiện tại:
- updateOn: Quyết định khi nào thì thao tác update dữ liệu vào trong $scope, thường là blur, default, kepress ....
- debounce: Giá trị của nó kiểu INT và nó quyết định sau khoảng bao lâu thì thao tác update dữ liệu vào $scope được thực hiện
- getterSetter: Chúng ta sẽ tìm hiểu thông qua phần 4 nhé, đơn giản nó là những phương thức get, set giống trong C++, C# hay PHP.
- Còn hai options nữa là allowInvalid, timezone nhưng chúng ta sẽ tìm hiểu nó sau nhé.
4. Các ví dụ về ng-model-options trong AngularJS
Sau đây chúng ta sẽ tìm hiểu một vài ví dụ liên quan đến Directive ng-model-options nhé, hãy chắc chắn rằng bạn đã đọc qua lý thuyết ở trên kia trước khi vào các ví dụ này.
Cách sử dụng ng-model-options (updateOn)
Trong ví dụ này ta sẽ thực hiện một chương trình như sau, chúng ta sẽ có một thẻ input và một thẻ span dùng để hiển thị giá trị của nó lúc nhập liệu. Chúng ta sẽ chia ra làm 2 bài, 1 bài có sử dụng options updateOn và một bài không có sử dụng.
Bài 1: Không sử dụng ng-model-options updateOn
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ví dụ sử dụng Directive</title> <style>*{margin:0}body{padding:20px}</style> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> <script language="javascript"> angular.module('myapp', []) .controller('optionsController', ['$scope', function($scope) { }]); </script> </head> <body ng-app="myapp"> <div ng-controller="optionsController"> <form name="userForm"> <h5>Nhập nội dung của bạn nào</h5> <input type="text" name="userName" ng-model="user.name"/><br /> <h5>Chuỗi mà Bạn đang nhập là:</h5> <span ng-bind="user.name"></span> </form> </div> </body> </html>
Khi bạn nhập dữ liệu thì bên dưới sẽ thay đổi theo bởi vì mình sử dụng cơ chế liên kết data binding (ng-bind).
Bài 2: Có sử dụng ng-model-options updateOn
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ví dụ sử dụng Directive</title> <style>*{margin:0}body{padding:20px}</style> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> <script language="javascript"> angular.module('myapp', []) .controller('optionsController', ['$scope', function($scope) { }]); </script> </head> <body ng-app="myapp"> <div ng-controller="optionsController"> <form name="userForm"> <h5>Nhập nội dung của bạn nào</h5> <input type="text" name="userName" ng-model-options="{updateOn:'blur'}" ng-model="user.name"/><br /> <h5>Chuỗi mà Bạn đang nhập là:</h5> <span ng-bind="user.name"></span> </form> </div> </body> </html>
Các bạn thấy ở ví dụ này mình có thêm thuộc tính ng-model-options="{updateOn:'blur'}"
có nghĩa rằng khi ta nhập dữ liệu và con trỏ chuột thoát khỏi ô input đó thì sự kiện update lưu vào trong $scope mới thực hiện chính vì vậy nó không thay đổi khi ta đang nhập.
Cách sử dụng ng-model-options (debounce)
Ví dụ: Trong ví dụ này ta sẽ xây dựng một ứng dụng tương tự như hai ví dụ trên, chỉ khác ở chỗ khi ta ngưng gõ khoảng thời gian 1 giây thì sự kiện update giá trị vào $scope mới thực hiện.
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ví dụ sử dụng Directive</title> <style>*{margin:0}body{padding:20px}</style> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> <script language="javascript"> angular.module('myapp', []) .controller('optionsController', ['$scope', function($scope) { }]); </script> </head> <body ng-app="myapp"> <div ng-controller="optionsController"> <form name="userForm"> <h5>Nhập nội dung của bạn nào</h5> <input type="text" name="userName" ng-model-options="{debounce:1000}" ng-model="user.name"/><br /> <h5>Chuỗi mà Bạn đang nhập là:</h5> <span ng-bind="user.name"></span> </form> </div> </body> </html>
Kết hợp debouce vaf updateOn
Chuyện gì sẽ xảy ra nếu ta kết hợp cả hai options này lại với nhau? Rất đơn giản nếu ta sử dụng nhiều options với nhau thì nó sẽ chạy từng options cho tới khi xong hết thì mới cập nhật $scope. Ví dụ dưới đây ta sẽ nhập vào và khi con trỏ chuột ra khỏi input thì khoảng 1 giây sau thì $scope được cập nhật, còn nếu ta không đưa con trỏ ra ngoài thì hành động cập nhật $scope này không được xử lý.
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ví dụ sử dụng Directive</title> <style>*{margin:0}body{padding:20px}</style> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> <script language="javascript"> angular.module('myapp', []) .controller('optionsController', ['$scope', function($scope) { }]); </script> </head> <body ng-app="myapp"> <div ng-controller="optionsController"> <form name="userForm"> <h5>Nhập nội dung của bạn nào</h5> <input type="text" name="userName" ng-model-options="{updateOn:'blur', debounce:1000}" ng-model="user.name"/><br /> <h5>Chuỗi mà Bạn đang nhập là:</h5> <span ng-bind="user.name"></span> </form> </div> </body> </html>
ng-model-options getterSetter
Bạn có từng nghe qua phương thức get, set trong C#, C++ hay thậm chí là PHP không nhỉ? Chắc là có rồi nên mình không nói nhiều nữa về vấn đề này nhé. Ví dụ dưới đây có sử dụng getterSetter, các bạn để ý kỹ nhé.
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ví dụ sử dụng Directive</title> <style>*{margin:0}body{padding:20px}</style> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script> <script language="javascript"> angular.module('myapp', []) .controller('optionsController', ['$scope', function($scope) { var _name = 'Freetuts.net'; $scope.user = { name: function(newName) { return angular.isDefined(newName) ? (_name = newName) : _name; } }; }]); </script> </head> <body ng-app="myapp"> <div ng-controller="optionsController"> <form name="userForm"> <h5>Nhập nội dung của bạn nào</h5> <input type="text" name="userName" ng-model-options="{ getterSetter: true }" ng-model="user.name"/><br /> <h5>Chuỗi mà Bạn đang nhập là:</h5> <span ng-bind="user.name()"></span> </form> </div> </body> </html>
Các bạn để ý thêm đoạn mã JS dưới đây:
var _name = 'Freetuts.net'; $scope.user = { name: function(newName) { return angular.isDefined(newName) ? (_name = newName) : _name; } };
<span ng-bind="user.name()"></span>
sẽ nhận được giá trị đó nên sẽ in ra ngoài trình duyệt.
5 Lời kết
Cũng hơi dài rồi nên mình sẽ ngưng bài viết tại đây, các bạn chú ý then chốt của bài này là hướng dẫn các bạn sử dụng Directive ngModelOptions để kết hợp với ngModel, mục đích cuối cùng là giúp bạn có cái nhìn tổng quát nên vẫn không thật sự đầy đủ cho lắm, các bạn lên mạng vào các trang nước ngoài và tìm hiểu thêm nhé. Bài tiếp theo chúng ta sẽ tìm hiểu về một Directive khác mà ta cũng từng sử dụng rồi, đó là ng-bind.