Giới thiệu

AngularJS framework JavaScript, nó có thể được thêm vào một trang HTML với một thẻ <script>.

AngularJS cho phép mở rộng các thuộc tính HTML bằng cách sử dụng các chỉ thị và các ràng buộc dữ liệu tới HTML bằng các biểu thức.

AngularJS mở rộng HTML

Để mở rộng HTML sử dụng AngularJS thì ta sử dụng các chỉ thị dạng  ng-directive.

Chỉ thị ng-app dùng để định nghĩa một ứng dụng AngularJS.

Chỉ thị ng-model sẽ liên kết dữ liệu của các điều khiển HTML (input, select, textarea) với dữ liệu ứng dụng.

Chỉ thị ng-bind sẽ liên kết dữ liệu ứng dụng với phần hiển thị HTML.

Ví dụ AngularJS

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>

<div ng-app="">
  <p>Name: <input type="text" ng-model="name"></p>
  <p ng-bind="name"></p>
</div>

</body>
</html>

Demo 

Giải thích ví dụ:

AngularJS tự động được khởi động khi trang web được tải.

Chỉ thị ng-app sẽ chỉ cho AngularJS rằng thẻ <div> là "chủ sở hữu" của một ứng dụng AngularJS.

Chỉ thị ng-model kết hợp giá trị của trường input với biến ứng dụng name.

Chỉ thị ng-bind liên kết innerHTML của phần tử <p> với biến ứng dụng name.

Chỉ thị AngularJS

Như bạn đã thấy, các chỉ thị AngularJS là thuộc tính HTML với tiền tố ng.

Chỉ thị ng-init khởi tạo các biến ứng dụng AngularJS.

Ví dụ AngularJS

<div ng-app="" ng-init="firstName='John'">

<p>The name is <span ng-bind="firstName"></span></p>

</div>

Thay thế giá trị HTML:

Ví dụ

<div data-ng-app="" data-ng-init="firstName='John'">

<p>The name is <span data-ng-bind="firstName"></span></p>

</div>

Ta có thể sử dụng data-ng- thay vì ng- nếu bạn muốn làm cho trang HTML trở nên có giá trị hơn.

Bạn sẽ học nhiều hơn về các chỉ thị ở những bài học phía sau.

Biểu thức trong AngularJS

Các biểu thức AngularJS được viết bên trong cặp ngoặc xoắn: {{ expression }}.

AngularJS sẽ "output" dữ liệu chính xác tại nơi viết biểu thức:

Ví dụ AngularJS

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div ng-app="">
  <p>My first expression: {{ 5 + 5 }}</p>
</div>

</body>
</html>

Biểu thức AngularJS liên kết dữ liệu AngularJS với HTML theo cách tương tự như chỉ thị ng-bind.

Ví dụ

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div ng-app="">
  <p>Name: <input type="text" ng-model="name"></p>
  <p>{{name}}</p>
</div>

</body>
</html>

Bạn sẽ được học nhiều hơn về biểu thức ở những bài học sau.

Ứng dụng AngularJS

Các module AngularJS dùng để định nghĩa các ứng dụng AngularJS.

Các controller AngularJS sẽ điều khiển các ứng dụng AngularJS.

Chỉ thị ng-app sẽ định nghĩa ứng dụng, chỉ thị ng-controller sẽ định nghĩa trình điều khiển.

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">

First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}

</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.firstName= "John";
    $scope.lastName= "Doe";
});

</script>

Các module AngularJS định nghĩa ứng dụng:

Module AngularJS

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

Các controller AngularJS điều khiển các ứng dụng:

app.controller('myCtrl', function($scope) {
    $scope.firstName= "John";
    $scope.lastName= "Doe";
});

Bạn sẽ được học sâu hơn về module và controller ở những bài học sau.

Biểu thức trong Angular

AngularJS liên kết dữ liệu tới HTML sử dụng biểu thức.

Các biểu thức AngularJS

Các biểu thức AngularJS có thể được viết bên trong dấu ngoặc kép: {{expression}}.

Biểu thức AngularJS cũng có thể được viết bên trong một chỉ thị: ng-bind = "expression".

AngularJS sẽ giải quyết các biểu thức, và trả lại kết quả chính xác nơi mà các biểu thức được viết.

Các biểu thức AngularJS giống như các biểu thức JavaScript: Chúng có thể chứa các chữ cái, toán tử và biến.

Ví dụ, {{ 5 + 5 }} hoặc {{ firstName + " " + lastName }}

Ví dụ

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div ng-app="">
  <p>My first expression: {{ 5 + 5 }}</p>
</div>

</body>
</html>

Nếu bạn bỏ chỉ thị ng-app, HTML sẽ không giải quyết được biểu thức:

Ví dụ

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div>
  <p>My first expression: {{ 5 + 5 }}</p>
</div>

</body>
</html>

Bạn có thể viết các biểu thức bất cứ khi nào bạn thích, AngularJS chỉ đơn giản là giải quyết các biểu thức và trả lại kết quả.

Ví dụ: Hãy để AngularJS thay đổi giá trị của thuộc tính CSS.

Thay đổi màu sắc của hộp nhập liệu dưới đây, bằng cách thay đổi giá trị của nó:

Thí dụ

<div ng-app="" ng-init="myCol='lightblue'">

<input style="background-color:{{myCol}}" ng-model="myCol" value="{{myCol}}">

</div>

Số trong AngularJS

Số trong AngularJS giống như số trong JavaScript:

Ví dụ

<div ng-app="" ng-init="quantity=1;cost=5">

<p>Total in dollar: {{ quantity * cost }}</p>

</div>

Ví dụ tương tự sau đây sử dụng ng-bind:

Ví dụ

<div ng-app="" ng-init="quantity=1;cost=5">

<p>Total in dollar: <span ng-bind="quantity * cost"></span></p>

</div>

Việc sử dụng ng-init là không được phổ biến lắm. Bạn nên học một cách tốt hơn là cách khởi tạo dữ liệu ở phần bài học nói về controller.

Chuỗi trong AngularJS

Chuỗi trong AngularJS giống như chuỗi trong JavaScript:

Ví dụ

<div ng-app="" ng-init="firstName='John';lastName='Doe'">

<p>The name is {{ firstName + " " + lastName }}</p>

</div>

Ví dụ tương tự có sử dụng ng-bind:

Ví dụ

<div ng-app="" ng-init="firstName='John';lastName='Doe'">

<p>The name is <span ng-bind="firstName + ' ' + lastName"></span></p>

</div>

Đối tượng trong AngularJS

Cũng tương tự như trong JavaScript:

Ví dụ

<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}">

<p>The name is {{ person.lastName }}</p>

</div>

Ví dụ tương tự sử dụng ng-bind:

Ví dụ

<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}">

<p>The name is <span ng-bind="person.lastName"></span></p>

</div>

Mảng trong AngularJS

Tương tự như mảng trong JavaScript:

Ví dụ

<div ng-app="" ng-init="points=[1,15,19,2,40]">

<p>The third result is {{ points[2] }}</p>

</div>

Ví dụ tương tự có sử dụng ng-bind:

Ví dụ

<div ng-app="" ng-init="points=[1,15,19,2,40]">

<p>The third result is <span ng-bind="points[2]"></span></p>

</div>

Biểu thức trong AngularJS so với trong JavaScript

Tương tự như biểu thức trong JavaScript, biểu thức trong AngularJS có thể chứa hằng, toán tử và biến.

Không giống như biểu thức trongJavaScript, biểu thức trong AngularJS có thể được viết biên trong phần HTML.

Biểu thức trong AngularJS không hỗ trợ phần điều kiện, vòng lặp và ngoại lệ.

Biểu thức trong AngularJS hỗ trợ việc lọc, trong JavaScript thì không.

Module trong Angular

Mỗi module trong AngularJS định nghĩa một ứng dụng.

Module là một bộ chứa các thành phần khác nhau của một ứng dụng.

Module là một bộ chứa cho các controller ứng dụng.

Các controller luôn luôn thuộc về một module.

Tạo module

Module được tạo bằng cách sử dụng hàm angular.module()

<div ng-app="myApp">...</div>

<script>

var app = angular.module("myApp", []); 

</script>

Tham số "myApp" tham chiếu tới một phần tử HTML trong đó ứng dụng sẽ chạy.

Bây giờ ta có thể thêm controller, chỉ thị, bộ lọc, ... vào ứng dụng AngularJS "myApp".

Thêm controller

Để thêm một controller tới ứng dụng của bạn ta thêm chỉ thị ng-controller:

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>

<script>

var app = angular.module("myApp", []);

app.controller("myCtrl"function($scope) {
    $scope.firstName = "John";
    $scope.lastName = "Doe";
});


</script>

Bạn sẽ học được nhiều hơn về controller ở bài sau bài này.

Thêm một chỉ thị

AngularJS có một tập các chỉ thị được xây dựng sẵn và bạn có thể dùng để thêm chức năng cho ứng dụng của bạn.

Ngoài ra bạn còn có thể sử dụng module để thêm chính chỉ thị của bạn cho các ứng dụng:

Ví dụ

<div ng-app="myApp" w3-test-directive></div>

<script> 
var app = angular.module("myApp", []);

app.directive("w3TestDirective"function() {
    return {
        template : "I was made in a directive constructor!"
    };
});

</script>

Bạn có thể học thêm về chỉ thị ở bài học phía sau.

Module và Controller trong các tập tin

Các ứng dụng trong AngularJS thường đẩy module và controller vào các file JavaScript.

Trong ví dụ này, "myApp.js" chứa một định nghĩa module ứng dụng, còn "myCtrl.js" chứa controller:

Ví dụ

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>

<script src="myApp.js"></script>
<script src="myCtrl.js"></script>

</body>
</html>

File myApp.js

var app = angular.module("myApp", []);

Tham số [] trong định nghĩa module có thể được sử dụng để định nghĩa các module phụ thuộc.

Ngoại trừ tham số [] bạn không tạo một module mới mà truy xuất vào module hiện thời.

File myCtrl.js

Những hàm có thể gây tác hại đến namespace Global

Các hàm Global cần phải được tránh trong JavaScript. Chúng có thể dễ dàng được ghi đè hoặc bị hủy bởi các kịch bản khác.

Các module AngularJS sẽ giúp giảm các hàm bằng cách đưa tất cả các hàm cục bộ vào module.

Khi nào thì cần tải thư viện

Trong khi thông thường các ứng dụng HTML thường đặt các kịch bản ở phía cuối thẻ <body> thì lời khuyên được đưa ra là bạn tải thư viện AngularJS vào trong thẻ <head> hoặc phía đầu của thẻ <body>.

Lý do là bởi việc gọi hàm angular.module chỉ có thể được biên dịch sau khi thư viện được load.

Ví dụ

<!DOCTYPE html>
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>

<script>
var app = angular.module("myApp", []);
app.controller("myCtrl"function($scope) {
    $scope.firstName = "John";
    $scope.lastName = "Doe";
});

</script>

</body>
</html>

Chỉ thị trong AngularJS

AngularJS cho phép bạn mở rộng HTML với các thuộc tính mới gọi là Chỉ thị (Directive).

AngularJS có một bộ các chỉ thị được xây dựng sẵn với các tác dụng tương ứng cho các ứng dụng của bạn.

AngularJS cũng cho phép bạn tự định nghĩa các chỉ thị của riêng bạn.

Chỉ thị trong AngularJS

Các chỉ thị AngularJS được dùng để mở rộng các thuộc tính HTML với tiền tố ng-.

Chỉ thị ng-app khởi tạo một ứng dụng AngularJS.

Chỉ thị ng-init khởi tạo dữ liệu ứng dụng.

Chỉ thị ng-model kết hợp giá trị của các điều khiển HTML (input, select, textarea) với dữ liệu ứng dụng.

Thí dụ

<div ng-app="" ng-init="firstName='John'">

<p>Name: <input type="text" ng-model="firstName"></p>
<p>You wrote: {{firstName}}</p>

</div>

Chỉ thị ng-app của AngularJS sẽ thông báo rằng thẻ <div> là chủ sở hữu của ứng dụng AngularJS.

Liên kết dữ liệu

Biểu thức {{firstName}} trong ví dụ ở trên là một biểu thức liên kết dữ liệu của AngularJS.

AngularJS sẽ liên kết các biểu thức AngularJS với dữ liệu AngularJS.

{{firstName}} tương ứng với ng-model="firstName".

Trong ví dụ tiếp theo đây hai trường văn bản cùng được đặt một loại chỉ thị ng-model:

Ví dụ

<div ng-app="" ng-init="quantity=1;price=5">

Số lượng: <input type="number" ng-model="quantity">
<br>
Giá:    <input type="number" ng-model="price">

Thành tiền: {{quantity * price}}

</div>

Việc sử dụng ng-init là không phổ biến, ta nên dùng cách khác để khởi tạo dữ liệu trong bài viết về controller.

Lặp các phần tử HTML

Chỉ thị ng-repeat sẽ lặp một phần tử HTML:

Ví dụ

<div ng-app="" ng-init="names=['Jani','Hege','Kai']">
  <ul>
    <li ng-repeat="x in names">
      {{x}}
    </li>
  </ul>
</div>

Chỉ thị ng-repeat thực ra dùng để nhân bản các phần tử HTML một lần cho mỗi mục trong tập hợp.

Chỉ thị ng-repeat được sử dụng trên một mảng các đối tượng:

Ví dụ

<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]"
>


<ul>
  <li ng-repeat="x in names">
    {{ x.name + ', ' + x.country }}
  </li>
</ul>

</div>

AngularJS rất tuyệt vời với các ứng dụng cơ sở dữ liệu CRUD (Create Read Update Delete).
Chỉ cần tưởng tượng điều gì sẽ xảy ra nếu những đối tượng này được lưu vào một database.

Chỉ thị ng-app

Chỉ thị ng-app dùng để xác định phần tử gốc của một ứng dụng AngularJS.

Chỉ thị ng-app sẽ auto-bootstrap (tự khởi động) ứng dụng khi trang web được load.

Chỉ thị ng-init

Chỉ thị ng-init dùng để xác định các giá trị khởi tạo cho ứng dụng AngularJS.

Thông thường thì bạn sẽ không sử dụng chỉ thị ng-init, thay vào đó bạn sẽ dùng một controller hoặc một module để thay thế.

Chỉ thị ng-model

Chỉ thị ng-model kết hợp giá trị của các điều khiển HTML (input, select, textarea) với dữ liệu ứng dụng.

Chỉ thị ng-model cũng có thể:

  • Cung cấp xác nhận kiểu cho dữ liệu ứng dụng (number, email, required).
  • Cung cấp trạng thái cho dữ liệu ứng dụng (không hợp lệ, lỗi).
  • Cung cấp các lớp CSS cho các phần tử HTML.
  • Liên kết phần tử HTML với các hình thức HTML.

Tạo các chỉ thị mới

Ngoài tất cả các chỉ thị AngularJS có sẵn, bạn có thể tạo các chỉ thị riêng của mình.

Các chỉ thị mới được tạo ra bằng cách sử dụng hàm .directive().

Để gọi ra chỉ thị mới, hãy tạo một phần tử HTML có cùng tên thẻ với chỉ thị mới.

Khi đặt tên cho một chỉ thị, bạn phải sử dụng phương pháp đặt theo kiểu lạc đà (V1Study chẳng hạn), nhưng khi gọi nó, bạn phải sử dụng tên riêng (v1-study chẳng hạn):

Thí dụ

<body ng-app="myApp">

<v1-study></v1-study>

<script>
var app = angular.module("myApp", []);
app.directive("V1Study"function() {
    return {
        template : "<h1>Made by a directive!</h1>"
    };
});

</script>

</body>

Bạn có thể gọi một thư mục bằng cách sử dụng:

  • Tên phần tử
  • Thuộc tính
  • Lớp
  • Chú thích

Các ví dụ dưới đây sẽ tạo ra cùng một kết quả:

Tên phần tử

<v1-study></v1-study>

Thuộc tính

<div v1-study></div>

Lớp

<div class="v1-study"></div>

Chú thích

<!-- directive: v1-study -->

Hạn chế

Bạn có thể hạn chế những chỉ thị của bạn để chỉ có thể được gọi bởi một số phương thức.

Ví dụ

Bằng cách thêm một thuộc tính restrict với giá trị "A", chỉ thị chỉ có thể được gọi bởi những thuộc tính (Atribute):

var app = angular.module("myApp", []);
app.directive("V1Study"function() {
    return {
        restrict : "A",
        template : "<h1>Made by a directive!</h1>"
    };
});

Những hạn chế phổ biến áp dụng cho chỉ thị:

  • E là tên phần tử (Element)
  • A là thuộc tính (Attribute)
  • C là lớp (Class)
  • M là chú thích (comMent)

Theo mặc định thì giá trị hạn chế là EA, tức là chỉ thị được gọi thông qua tên phần tử và thuộc tính.

Model trong Angular

Chỉ thị ng-model liên kết giá trị của các điều khiển HTML (input, select, textarea) với dữ liệu ứng dụng.

Chỉ thị ng-model

Với chỉ thị ng-model bạn có thể liên kết giá trị của một trường input với một biến được tạo trong AngularJS.

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
    Name: <input ng-model="name">
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.name = "John Doe";
});

</script>

Hai cách liên kết

Việc liên kết có thể thực hiện theo 2 cách. Nếu người dùng thay đổi giá trị trong trường input thì thuộc tính AngularJS cũng sẽ thay đổi giá trị của nó:

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
    Name: <input ng-model="name">
    <h1>You entered: {{name}}</h1>
</div>

Kiểm tra giá trị nhập vào của người dùng

Chỉ thị ng-model có thể cung cấp các định kiểu cho dữ liệu ứng dụng (number, e-mail, required).

Ví dụ

<form ng-app="" name="myForm">
    Email:
    <input type="email" name="myAddress" ng-model="text">
    <span ng-show="myForm.myAddress.$error.email">Not a valid e-mail address</span>
</form>

Trong ví dụ trên, thẻ <span> sẽ được hiển thị chỉ khi biểu thức trong thuộc tính ng-show trả về true.

Nếu thuộc tính trong ng-model không có sẵn thì AngularJS sẽ tạo cho bạn.

Trạng thái ứng dụng

Chỉ thị ng-model có thể cung cấp trạng thái cho dữ liệu ứng dụng (không hợp lệ, không đúng, chạm, lỗi):

Ví dụ

<form ng-app="" name="myForm" ng-init="myText = 'post@myweb.com'">
    Email:
    <input type="email" name="myAddress" ng-model="myText" required>
    <h1>Status</h1>
    {{myForm.myAddress.$valid}}
    {{myForm.myAddress.$dirty}}
    {{myForm.myAddress.$touched}}
</form>

Các lớp CSS

Chỉ thị ng-model cung cấp các lớp CSS cho các phần tử HTML phụ thuộc vào trạng thái của chúng:

Ví dụ

<style>
input.ng-invalid {
    background-color: lightblue;
}
</style>
<body>

<form ng-app="" name="myForm">
    Enter your name:
    <input name="myName" ng-model="myText" required>
</form>

Chỉ thị ng-model sẽ thêm/xóa các lớp sau tùy thuộc vào trạng thái của trường của form:

  • ng-empty
  • ng-not-empty
  • ng-touched
  • ng-untouched
  • ng-valid
  • ng-invalid
  • ng-dirty
  • ng-pending
  • ng-pristine

Data Binding trong AngularJS

Data binding trong AngularJS là sự đồng bộ giữa model và view.

Data Model

Các ứng dụng AngularJS thường có một data model. Data model là một tập hợp các dữ liệu dùng cho ứng dụng.

Ví dụ

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.firstname "John";
    $scope.lastname = "Doe";
});

 

HTML View

Bộ chứa HTML trong đó ứng dụng AngularJS được hiển thị gọi là view.

View truy xuất vào model và có một số cách hiển thị model data trong view.

Bạn có thể sử dụng chỉ thị ng-bind, chỉ thị này sẽ lấy dữ liệu từ thuộc tính innerHTML của phần tử để hiển thị thuộc tính model cụ thể:

Ví dụ

<p ng-bind="firstname"></p>

Bạn cũng có thể sử dụng hai cặp ngoặc xoắn để hiển thị nội dung từ model:

Ví dụ

<p>First name: {{firstname}}</p>

Hoặc bạn cũng có thể sử dụng chỉ thị ng-model trong các điều khiển HTML để liên kết model và view.

Chỉ thị ng-model

Dùng chỉ thị ng-model để liên kết model với view trong các điều khiển HTML (input, select, textarea).

Ví dụ

<input ng-model="firstname">

Chỉ thị ng-model cung cấp hai cách liên kết giữa model và view.

Hai cách liên kết

Data binding trong AngularJS là sự đồng bộ giữa model và view.

Khi dữ liệu trong model thay đổi thì view sẽ phản ánh sự thay đổi đó, và khi dữ liệu trong view thay đổi thì model cũng được cập nhật, điều này xảy ra một cách trực tiếp và tự động để đảm bảo rằng model và view luôn luôn được update.

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
    Name: <input ng-model="firstname">
    <h1>{{firstname}}</h1>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.firstname = "John";
    $scope.lastname = "Doe";
});
</script>

AngularJS Controller

Các ứng dụng trong AngularJS được điều khiển bằng các controller.

Do có sự đồng bộ ngay lập tức của model và view nên controller có thể được tách hoàn toàn khỏi cơ chế view và chỉ tập trung vào dữ liệu model. Nhờ sự ràng buộc dữ liệu trong AngularJS và view sẽ phản ánh bất kỳ sự thay đổi nào trong controller.

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
    <h1 ng-click="changeName()">{{firstname}}</h1>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.firstname = "John";
    $scope.changeName = function() {
        $scope.firstname = "Nelly";
    }
});
</script>

Controller trong AngularJS

Các controller trong AngularJS có nhiệm vụ kiểm soát dữ liệu của các ứng dụng AngularJS.

Controller là đối tượng JavaScript thông thường.

Controller

Các ứng dụng AngularJS được điều khiển bởi các controller.

Chỉ thị ng-controller định nghĩa controller của ứng dụng.

Controller là một đối tượng JavaScript, được tạo bởi một hàm tạo đối tượng JavaScript chuẩn.

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">

First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{firstName + " " + lastName}}

</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.firstName = "John";
    $scope.lastName = "Doe";
});
</script>

Giải thích:

Ứng dụng AngularJS được định nghĩa bởi  ng-app = "myApp". Ứng dụng chạy bên trong thẻ <div>.

Thuộc tính ng-controller = "myCtrl" là một chỉ thị AngularJS. Nó định nghĩa một controller.

Hàm myCtrl là một hàm JavaScript.

AngularJS sẽ gọi controller với đối tượng $scope.

Trong AngularJS, $scope là đối tượng ứng dụng (chủ sở hữu các biến ứng dụng và các hàm).

Controller tạo ra hai thuộc tính (biến) là firstName và lastName.

Chỉ thị ng-model liên kết các trường đầu vào với các thuộc tính của controller (firstName và lastName).

Các phương thức của controller

Ví dụ trên minh họa một đối tượng controller với hai thuộc tính: lastName và firstName.

Một controller cũng có thể có các phương thức (các biến dưới dạng các hàm):

Ví dụ

<div ng-app="myApp" ng-controller="personCtrl">

First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{fullName()}}

</div>

<script>
var app = angular.module('myApp', []);
app.controller('personCtrl'function($scope) {
    $scope.firstName = "John";
    $scope.lastName = "Doe";
    $scope.fullName = function() {
        return $scope.firstName + " " + $scope.lastName;
    };
});
</script>

Controller trong các file ngoài

Trong các ứng dụng lớn hơn thì các controller được lưu trữ trong các tập tin bên ngoài.

Dưới đây là ví dụ trong đó các controller được lưu trong file personController.js :

Ví dụ

<div ng-app="myApp" ng-controller="personCtrl">

First Name: <input type="text" ng-model="firstName"><br>
Last Name: <input type="text" ng-model="lastName"><br>
<br>
Full Name: {{fullName()}}

</div>

<script src="personController.js"></script>

Một ví dụ khác

Trong ví dụ tiếp theo, chúng ta sẽ tạo một file controller mới:

angular.module('myApp', []).controller('namesCtrl', function($scope) {
    $scope.names = [
        {name:'Jani',country:'Norway'},
        {name:'Hege',country:'Sweden'},
        {name:'Kai',country:'Denmark'}
    ];
});

Lưu file với tên namesController.js :

Và sau đó sử dụng tập tin điều khiển trong một ứng dụng.

Ví dụ

<div ng-app="myApp" ng-controller="namesCtrl">

<ul>
  <li ng-repeat="x in names">
    {{ x.name + ', ' + x.country }}
  </li>
</ul>

</div>

<script src="namesController.js"></script>

Scope trong AngularJS

Scope là sự gắn kết giữa HTML (view) và JavaScript (controller).

Scope là một đối tượng bao hàm cả các thuộc tính và phương thức..

Scope bao hàm cả view và controller.

Cách sử dụng Scope

Khi bạn tạo một controller trong AngularJS thì bạn truyền đối tượng $scope đi dưới dạng đối số.

Ví dụ

Các thuộc tính được tạo trong controller có thể được tham chiếu trong view:

<div ng-app="myApp" ng-controller="myCtrl">
 
<h1>{{carname}}</h1>

</div>

<script>
var app = angular.module('myApp', []);

app.controller('myCtrl'function($scope) {
    $scope.carname = "Volvo";
});
</script>

Khi thêm các thuộc tính vào đối tượng $scope trong controller thì view (HTML) sẽ truy cập được tới các thuộc tính này.

Trong view thì bạn không sử dụng tiền tố $scope, mà bạn chỉ cần gọi trực tiếp các thuộc tính và phương thức của $scope theo dạng {{tên_thuộc_tính của $scope}}.

Hiểu sâu hơn về Scope

Giả sử ta có một ứng dụng AngularJS bao gồm:

  • View, là HTML.
  • Model, là dữ liệu sử dụng cho view.
  • Controller, là hàm JavaScript dùng để tạo/sửa/xóa/điều phối dữ liệu.

Thì các thuộc tính hay phương thức của scope chính là Model.

Scope là một đối tượng JavaScript bao gồm các thuộc tính và phương thức áp dụng được cho cả view và controller.

Ví dụ

Nếu bạn thay đổi view thì model và controller sẽ được update:

<div ng-app="myApp" ng-controller="myCtrl">

<input ng-model="name">

<h1>My name is {{name}}</h1>

</div>

<script>
var app = angular.module('myApp', []);

app.controller('myCtrl'function($scope) {
    $scope.name = "John Doe";
});
</script>

Nắm rõ Scope

Nắm rõ được Scope sẽ rất quan trọng để biết được scope đang xử lý ở phạm vi nào, vào thời điểm nào.

Trong hai ví dụ trên thì chỉ có một scope, vì thế việc nắm rõ về scope không khó, nhưng với một lượng lớn các ứng dụng có thể có chứa các phần trong DOM HTML thì chỉ có thể truy cập một số scope nhất định.

Ví dụ

Khi sử dụng chỉ thị ng-repeat thì mỗi lần lặp lại sẽ có quyền truy cập được vào đối tượng lặp hiện thời:

<div ng-app="myApp" ng-controller="myCtrl">

<ul>
    <li ng-repeat="x in names">{{x}}</li>
</ul>

</div>

<script>
var app = angular.module('myApp', []);

app.controller('myCtrl'function($scope) {
    $scope.names = ["Emil""Tobias""Linus"];
});
</script>

Mỗi phần tử <li> sẽ truy cập tới đối tượng lặp hiện thời mà trong trường hợp này là đối tượng chuỗi, là đối tượng được tham chiếu bằng cách sử dụng x.

Scope gốc

Tất cả các ứng dụng đều có một $rootScope là scope được tạo trên phần tử HTML chứa chỉ thị ng-app.

$rootScope có sẵn trong toàn bộ ứng dụng.

Nếu một biến có cùng tên trong cả scope hiện thời và  rootScope, thì ứng dụng sẽ sử dụng biến đó trong scope hiện thời.

Ví dụ

Một biến có tên "color" có sẵn trong cả scope của controller và rootScope:

<body ng-app="myApp">

<p>Màu yêu thích của rootScope:</p>
<h1>{{color}}</h1>

<div ng-controller="myCtrl">
    <p>scope của màu yêu thích của controller:</p>
    <h1>{{color}}</h1>
</div>

<p>Màu yêu thích của rootScope vẫn là:</p>
<h1>{{color}}</h1>

<script>
var app = angular.module('myApp', []);
app.run(function($rootScope) {
    $rootScope.color = 'blue';
});
app.controller('myCtrl'function($scope) {
    $scope.color = "red";
});
</script>
</body>

Filter trong AngularJS

Filter có thể được thêm vào AngularJS để định dạng (format) dữ liệu.

Các loại filter trong AngularJS

AngularJS cung cấp các loại filter sau để chuyển đổi dữ liệu:

  • currency Chuyển số sang dạng tiền tệ.
  • date Chuyển ngày sang định dạng được chỉ định.
  • filter Chọn một tập con từ một mảng.
  • json Định dạng đối tượng thành chuỗi JSON.
  • limitTo Giới hạn một mảng/chuỗi thành một số phần tử/ký tự được chỉ định.
  • lowercase Chuyển chuỗi thành dạng in thường.
  • uppercase Chuyển chuỗi thành chữ in hoa.
  • number Chuyển số thành chuỗi.
  • orderBy Sắp xếp mảng bằng một biểu thức.

Thêm filter cho biểu thức

Filter có thể được thêm vào biểu thức bằng cách sử dụng ký tự | (pipe) nằm trước filter.

Ví dụ sau thêm filter uppercase vao biểu thức để chuyển chuỗi thành chữ in hoa:

<div ng-app="myApp" ng-controller="personCtrl">

<p>The name is {{ lastName | uppercase }}</p>

</div>

Thêm Filter vào chỉ thị

Filter được thêm vào chỉ thị chẳng hạn như ng-repeat cũng bằng cách sử dụng | đặt trước filter.

Ví dụ

Thêm filter orderBy để sắp xếp mảng:

<div ng-app="myApp" ng-controller="namesCtrl">

<ul>
  <li ng-repeat="x in names | orderBy:'country'">
    {{ x.name + ', ' + x.country }}
  </li>
</ul>

</div>

Filter currency

Filter currency dùng để định dạng tiền tệ với chuỗi số.

Ví dụ

<div ng-app="myApp" ng-controller="costCtrl">

<h1>Price: {{ price | currency }}</h1>

</div>

Filter filter

Filter filter dùng để lấy một tập con của một mảng.

Filter này có thể sử dụng cho mảng hoặc chuỗi và nó sẽ trả về một mảng hoặc chuỗi con chỉ chứa các mục tương thích với yêu cầu.

Nếu chuỗi cần filter là rỗng thì tương ứng với lấy toàn bộ mảng.

Ví dụ

Trả về các tên chứa ký tự 'i':

<div ng-app="myApp" ng-controller="namesCtrl">

<ul>
  <li ng-repeat="x in names | filter : 'i'">
    {{ x | filter: '8'}}
  </li>
</ul>

</div>

Lọc một mảng theo dữ liệu người dùng nhập vào

Bằng cách đặt chỉ thị ng-model cho thẻ <input> ta có thể sử dụng giá trị của thẻ này như là một biểu thức trong một filter.

Ví dụ

<div ng-app="myApp" ng-controller="namesCtrl">

<p><input type="text" ng-model="test"></p>

<ul>
  <li ng-repeat="x in names | filter : test">
    {{ x }}
  </li>
</ul>

</div>

Sắp xếp một mảng dựa trên giá trị nhập vào

Bằng cách thêm chỉ thị ng-click vào cột tiêu đề của bảng ta có thể thực hiện hàm thay đổi thứ tự sắp xếp của mảng.

Ví dụ

<div ng-app="myApp" ng-controller="namesCtrl">

<table border="1" width="100%">
  <tr>
    <th ng-click="orderByMe('name')">Name</th>
    <th ng-click="orderByMe('country')">Country</th>
  </tr>
  <tr ng-repeat="x in names | orderBy:myOrderBy">
    <td>{{x.name}}</td>
    <td>{{x.country}}</td>
  </tr>
</table>

</div>

<script>
angular.module('myApp', []).controller('namesCtrl'function($scope) {
  $scope.names = [
    {name:'Jani',country:'Norway'},
    {name:'Carl',country:'Sweden'},
    {name:'Margareth',country:'England'},
    {name:'Hege',country:'Norway'},
    {name:'Joe',country:'Denmark'},
    {name:'Gustav',country:'Sweden'},
    {name:'Birgit',country:'Denmark'},
    {name:'Mary',country:'England'},
    {name:'Kai',country:'Norway'}
  ];
  $scope.orderByMe = function(x) {
    $scope.myOrderBy = x;
  }
});
</script>

Tự tạo filter

Ta có thể tự tạo filter bằng cách đăng ký một hàm filter mới cho module của mình.

Ví dụ

Tạo một filter có tên "myFormat":

<ul ng-app="myApp" ng-controller="namesCtrl">
    <li ng-repeat="x in names">
        {{x | myFormat}}
    </li>
</ul>

<script>
var app = angular.module('myApp', []);
app.filter('myFormat'function() {
    return function(x) {
        var i, c, txt = "";
        for (i = 0; i < x.length; i++) {
            c = x[i];
            if (i % 2 == 0) {
                c = c.toUpperCase();
            }
            txt += c;
        }
        return txt;
    };
});
app.controller('namesCtrl'function($scope) {
    $scope.names = ['Jani''Carl''Margareth''Hege''Joe''Gustav''Birgit''Mary''Kai'];
});
</script>

Filter myFormat chuyển tất cả các ký tự có chỉ số chẵn (0, 2, 4, ...) thành dạng ký tự in hoa.

Service trong AngularJS

Trong AngularJS ta có thể tự tạo service hoặc sử dụng các service sẵn có.

Service là gì?

Trong AngularJS, một service là một function hoặc một đối tượng sẵn có và được giới hạn trong ứng dụng AngularJS của bạn.

AngularJS có khoảng 30 service được tích hợp sẵn, một trong số chúng là service $location.

Service $location có các phương thức trả về thông tin về vị trí của trang web hiện thời.

Ví dụ

Sử dụng service $location trong một controller:

var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $location) {
    $scope.myUrl = $location.absUrl();
});

Demo »

Lưu ý rằng service $location được truyền trong controller dưới dạng đối số. Để sử dụng service trong controller thì nó phải được định nghĩa như một dependency.

Vì sao phải sử dụng Service?

Với nhiều service có vẻ như ta có thể các đối tượng đã có trong DOM như window.location, nhưng nó có những giới hạn nhất định, ít nhất là đối với ứng dụng AngularJS.

AngularJS liên tục giám sát ứng dụng của bạn và để nó xử lý được các thay đổi và sự kiện đúng cách thì AngularJS muốn bạn sử dụng service $location thay vì đối tượng window.location.

Service $http

Service $http là một trong những service phổ biến nhất trong các ứng dụng AngularJS. Service này sẽ tạo một yêu cầu tới server, và để cho ứng dụng của ta xử lý phản hồi.

Ví dụ

Sử dụng service $http để yêu cầu dữ liệu từ server:

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $http) {
    $http.get("welcome.htm").then(function (response) {
        $scope.myWelcome = response.data;
    });
});

Demo »

Service $timeout

Service $timeout ứng với hàm window.setTimeout.

Ví dụ

Hiển thị một thông báo mới sau 2 giây:

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $timeout) {
    $scope.myHeader = "Hello World!";
    $timeout(function () {
        $scope.myHeader = "How are you today?";
    }, 2000);
});

Demo »

Service $interval

Service $interval ứng với hàm window.setInterval.

Ví dụ

Hiển thị thời gian theo từng giây:

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $interval) {
    $scope.theTime = new Date().toLocaleTimeString();
    $interval(function () {
        $scope.theTime = new Date().toLocaleTimeString();
    }, 1000);
});

Demo »

Tự tạo Service

Ta có thể tự tạo service của riêng ta như sau:

Tạo một service có tên hexafy:

app.service('hexafy'function() {
    this.myFunc = function (x) {
        return x.toString(16);
    }
});

Để sử dụng service tự tạo thì ta thêm nó như là một dependency khi định nghĩa controller.

Ví dụ

Sử dụng service tự tạo hexafy ở trên để chuyển số thành số hệ 16 (hexa):

app.controller('myCtrl'function($scope, hexafy) {
    $scope.hex = hexafy.myFunc(255);
});

Demo »

Sử dụng Service tự tạo trong Filter

Một khi service đã kết nối tới ứng dụng của bạn thì bạn có thể sử dụng nó trong bất kỳ controller, chỉ thị, filter nào kể cả là bên trong các service khác.

Để sử dụng service bên trong filter thì ta thêm nó như là một dependency khi định nghĩa filter.

Ví dụ

Service hexafy được sử dụng trong filter myFormat:

app.filter('myFormat',['hexafy'function(hexafy) {
    return function(x) {
        return hexafy.myFunc(x);
    };
}]);

Sau đó bạn cũng có thể sử dụng filter khi hiển thị các giá trị của một đối tượng hoặc một mảng.

Ví dụ

Tạo một service có tên hexafy:

<ul>
<li ng-repeat="x in counts">{{x | myFormat}}</li>
</ul>

HTTP trong AngularJS AJAX

$http là một service AngularJS dùng để đọc dữ liệu từ máy chủ từ xa (remote).


Service $http

Service $http tạo một yêu cầu (request) tới server, và trả về một response.

Ví dụ

Tạo một request tới server, và hiển thị kết quả trong header:

<div ng-app="myApp" ng-controller="myCtrl"> 

<p>Today's welcome message is:</p>
<h1>{{myWelcome}}</h1>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $http) {
    $http.get("welcome.htm")
    .then(function(response) {
        $scope.myWelcome = response.data;
    });
});
</script>

Các phương thức của service $http

Ví dụ trên sử dụng phương thức .get của service $http.

Phương thức .get là một phương thức thu gọn của service $http. Có một số phương thức thu gọn như sau:

  • .delete()
  • .get()
  • .head()
  • .jsonp()
  • .patch()
  • .post()
  • .put()

Ví dụ:

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $http) {
    $http({
        method : "GET",
        url : "welcome.htm"
    }).then(function mySuccess(response) {
        $scope.myWelcome = response.data;
    }, function myError(response) {
        $scope.myWelcome = response.statusText;
    });
});

Ví dụ trên thực thi service $http với một đối tượng dưới dạng một đối số. Đối tượng sẽ xác định phương thức HTTP, url, phải làm gì khi xử lý thành công, và phải làm gì khi gặp lỗi.


Các thuộc tính

Phản hồi từ server sẽ là một đối tượng gồm những thuộc tính sau:

  • .config đối tượng sử dụng để tạo request.
  • .data là một chuỗi hoặc một đối tượng chứa phản hồi từ server.
  • .headers là một hàm dùng để lấy thông tin header.
  • .status một số xác định trạng thái của HTTP.
  • .statusText một chuỗi xác định trạng thái HTTP.

Ví dụ

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $http) {
    $http.get("welcome.htm")
    .then(function(response) {
        $scope.content = response.data;
        $scope.statuscode = response.status;
        $scope.statustext = response.statusText; 
    });
});

Để xử lý lỗi bạn thêm một hoặc nhiều hàm tới phương thức .then:

Ví dụ

var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope, $http) {
    $http.get("wrongfilename.htm")
    .then(function(response) {
        //First function handles success
        $scope.content = response.data;
    }, function(response) {
        //Second function handles error
        $scope.content = "Something went wrong";
    });
});

JSON

Dữ liệu bạn lấy từ phản hồi (response) được ở định dạng JSON.

JSON là một cách rất hay để truyền dữ liệu, và nó dễ sử dụng trong AngularJS cũng như trong JavaScript.

Ví dụ: Trên server ta có một file trả về một đối tượng JSON có chứa 15 khách hàng, tất cả đều được gộp vào một mảng gọi là records.

Ví dụ

Chỉ thị ng-repeat là cách hoàn hảo đề lặp một mảng:

<div ng-app="myApp" ng-controller="customersCtrl"> 

<ul>
  <li ng-repeat="x in myData">
    {{ x.Name + ', ' + x.Country }}
  </li>
</ul>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $http) {
    $http.get("customers.php").then(function(response) {
        $scope.myData = response.data.records;
    });
});
</script>

Giải thích:

Ứng dụng định nghĩa controller customersCtrl, với một $scope và một $http.

$http là một đối tượng XMLHttpRequest dùng để request dữ liệu ngoài.

$http.get() sẽ đọc dữ liệu JSON từ file http://v1study.com/customers.php.

Khi thành công thì controller sẽ tạo một thuộc tính tên myData trong scope, với dữ liệu JSON từ server.

Nguồn: https://www.w3schools.com/angular/angular_http.asp

Table trong AngularJS

Chỉ thị ng-repeat là cách tốt nhất để hiển thị bảng dữ liệu trong AngularJS.


Hiển thị dữ liệu trong bảng

Việc hiển thị bảng với AngularJS rất đơn giản:

Ví dụ AngularJS

<div ng-app="myApp" ng-controller="customersCtrl"> 

<table>
  <tr ng-repeat="x in names">
    <td>{{ x.Name }}</td>
    <td>{{ x.Country }}</td>
  </tr>
</table>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $http) {
    $http.get("customers.php")
    .then(function (response) {$scope.names = response.data.records;});
});
</script>

Hiển thị với style CSS

Để kết quả hiển thị được đẹp thì ta đưa vô trang một số thuộc tính CSS:

CSS Style

<style>
table, th , td {
  border: 1px solid grey;
  border-collapse: collapse;
  padding: 5px;

}
table tr:nth-child(odd) {
  background-color: #f1f1f1;
}
table tr:nth-child(even) {
  background-color: #ffffff;
}
</style>

Display with orderBy Filter

Để sắp xếp bảng ta thêm filter orderBy

Ví dụ

<table>
  <tr ng-repeat="x in names | orderBy : 'Country'">
    <td>{{ x.Name }}</td>
    <td>{{ x.Country }}</td>
  </tr>
</table>

Hiển thị với filter uppercase

Để hiển thị chữ in hoa ta sử dụng filter uppercase

Ví dụ

<table>
  <tr ng-repeat="x in names">
    <td>{{ x.Name }}</td>
    <td>{{ x.Country | uppercase }}</td>
  </tr>
</table>

Hiển thị chỉ mục bảng ($index)

Để hiển thị chỉ mục của bảng ta thêm một cột <td> chứa $index

Ví dụ

<table>
  <tr ng-repeat="x in names">
    <td>{{ $index + 1 }}</td>
    <td>{{ x.Name }}</td>
    <td>{{ x.Country }}</td>
  </tr>
</table>

Sử dụng $even và $odd

Ví dụ

<table>
<tr ng-repeat="x in names">
<td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Name }}</td>
<td ng-if="$even">{{ x.Name }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">{{ x.Country }}</td>
<td ng-if="$even">{{ x.Country }}</td>
</tr>
</table>

Select trong AngularJS

AngularJS cho phép ta tạo dropdown list dựa trên các phần tử mảng hay một đối tượng.


Tạo Select Box dùng chỉ thị ng-options

Nếu bạn muốn tạo một dropdown list dựa trên một đối tượng object hoặc một mảng trong AngularJS thì bạn cần dùng chỉ thị ng-options:

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">

<select ng-model="selectedName" ng-options="x for x in names">
</select>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.names = ["Emil""Tobias""Linus"];
});
</script>

ng-options và ng-repeat

Bạn cũng có thể sử dụng chỉ thị ng-repeat để tạo dropdown list:

Example

<select>
<option ng-repeat="x in names">{{x}}</option>
</select>

Vì chỉ thị ng-repeat sẽ lặp một khối mã HTML của mỗi phần tử trong mảng nên nó có thể được sử dụng để tạo các option trong dropdown list, nhưng chỉ thị ng-options đã tạo lại được dùng để điền một dropdown list với các option, điều này sẽ có ít nhất một lợi điểm:

Dropdown được tạo từ ng-options cho phép giá trị được chọn là một object, còn dropdown được tạo bằng ng-repeat lại có dạng string.

Bạn chọn gì?

Giả sử bạn có một mảng các đối tượng như sau:

$scope.cars = [
    {model : "Ford Mustang", color : "red"},
    {model : "Fiat 500", color : "white"},
    {model : "Volvo XC90", color : "black"}
];

Thì chỉ thị ng-repeat có hạn chế là giá trị được chọn phải là một chuỗi:

Ví dụ

Sử dụng ng-repeat:

<select ng-model="selectedCar">
<option ng-repeat="x in cars" value="{{x.model}}">{{x.model}}</option>
</select>

<h1>You selected: {{selectedCar}}</h1>

Khi sử dụng chỉ thị ng-options thì giá trị được chọn có thể là một đối tượng:

Ví dụ

Sử dụng ng-options:

<select ng-model="selectedCar" ng-options="x.model for x in cars">
</select>

<h1>You selected: {{selectedCar.model}}</h1>
<p>Its color is: {{selectedCar.color}}</p>

Khi giá trị được chọn có thể là một đối tượng thì nó có thể mang thông tin và ứng dụng của bạn có thể linh hoạt hơn.

Chúng ta sử dụng chỉ thị ng-options trong bài viết này.


Trong các ví dụ trước thì nguồn dữ liệu là mảng, nhưng ta cũng có thể sử dụng một đối tượng.

Giả sử rằng ta có một đối tượng có các cặp key-value như sau:

$scope.cars = {
    car01 : "Ford",
    car02 : "Fiat",
    car03 : "Volvo"
};

Thì biểu thức trong thuộc tính ng-options hơi khác một chút so với các đối tượng:

Ví dụ

Sử dụng đối tượng như là một nguồn dữ liệu, trong đó x biểu diễn cho key, còn y biểu diễn cho value:

<select ng-model="selectedCar" ng-options="x for (x, y) in cars">
</select>

<h1>You selected: {{selectedCar}}</h1>

Giá trị đã chọn sẽ luôn luôn là value trong cặp key-value.

value trong cặp key-value cũng có thể là một đối tượng.

Ví dụ

Giá trị đã chọn sẽ vẫn là value trong cặp key-value, nhưng lần này nó là đối tượng:

$scope.cars = {
car01 : {brand : "Ford", model : "Mustang", color : "red"},
car02 : {brand : "Fiat", model : "500", color : "white"},
car03 : {brand : "Volvo", model : "XC90", color : "black"}
};

Các option của dropdown list không phải là key trong cặp key-value, nó có thể là value hoặc một thuộc tính của đối tượng value:

Ví dụ

<select ng-model="selectedCar" ng-options="y.brand for (x, y) in cars">
</select>

SQL trong AngularJS

AngularJS rất tuyệt vời trong việc hiển thị dữ liệu từ Database, bạn chỉ cần đảm bảo rằng dữ liệu có dạng JSON.

Lấy dữ liệu từ PHP Server chạy MySQL

Ví dụ

<div ng-app="myApp" ng-controller="customersCtrl">

<table>
  <tr ng-repeat="x in names">
    <td>{{ x.Name }}</td>
    <td>{{ x.Country }}</td>
  </tr>
</table>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $http) {
    $http.get("customers_mysql.php")
    .then(function (response) {$scope.names = response.data.records;});
});
</script>

Lấy dữ liệu từ ASP.NET Server chạy SQL

Ví dụ

<div ng-app="myApp" ng-controller="customersCtrl">

<table>
  <tr ng-repeat="x in names">
    <td>{{ x.Name }}</td>
    <td>{{ x.Country }}</td>
  </tr>
</table>

</div>

<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $http) {
    $http.get("customers_sql.aspx")
    .then(function (response) {$scope.names = response.data.records;});
});
</script>

Các ví dụ về Server Code

Sau đây là danh sách server code dùng để lấy dữ liệu SQL.

  1. Dùng PHP và MySQL => trả về JSON.
  2. Dùng PHP và MS Access => trả về JSON.
  3. Dùng ASP.NET, VB, và MS Access => trả về JSON.
  4. Dùng ASP.NET, Razor, và SQL Lite => trả về JSON.

Các yêu cầu HTTP Cross-Site

Các yêu cầu cho dữ liệu từ một server khác (so với trang yêu cầu), được gọi là các yêu cầu HTTP cross-site.

Các yêu cầu cross-site rất phổ biến trên trang web. Có nhiều trang load CSS, ảnh và script từ các nhiều server khác nhau.

Trong các trình duyệt hiện đại thì các yêu cầu HTTP cross-site từ script bị giới hạn ở cùng một site vì lý do bảo mật.

Dòng lệnh sau trong ví dụ PHP được thêm vào để cho phép truy cập cross-site.

header("Access-Control-Allow-Origin: *");

1. Server Code PHP và MySQL

<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");

$conn = new mysqli("myServer""myUser""myPassword""Northwind");

$result = $conn->query("SELECT CompanyName, City, Country FROM Customers");

$outp = "";
while($rs = $result->fetch_array(MYSQLI_ASSOC)) {
    if ($outp != "") {$outp .= ",";}
    $outp .= '{"Name":"'  . $rs["CompanyName"] . '",';
    $outp .= '"City":"'   . $rs["City"]        . '",';
    $outp .= '"Country":"'. $rs["Country"]     . '"}';
}
$outp ='{"records":['.$outp.']}';
$conn->close();

echo($outp);
?>

2. Server Code PHP và MS Access

<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=ISO-8859-1");

$conn = new COM("ADODB.Connection");
$conn->open("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=Northwind.mdb");

$rs = $conn->execute("SELECT CompanyName, City, Country FROM Customers");

$outp = "";
while (!$rs->EOF) {
    if ($outp != "") {$outp .= ",";}
    $outp .= '{"Name":"'  . $rs["CompanyName"] . '",';
    $outp .= '"City":"'   . $rs["City"]        . '",';
    $outp .= '"Country":"'. $rs["Country"]     . '"}';
    $rs->MoveNext();
}
$outp ='{"records":['.$outp.']}';

$conn->close();

echo ($outp);
?>

3. Server Code ASP.NET, VB và MS Access

<%@ Import Namespace="System.IO"%>
<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.Data.OleDb"%>
<%
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Response.AppendHeader("Content-type", "application/json")
Dim conn As OleDbConnection
Dim objAdapter As OleDbDataAdapter
Dim objTable As DataTable
Dim objRow As DataRow
Dim objDataSet As New DataSet()
Dim outp
Dim c
conn = New OledbConnection("Provider=Microsoft.Jet.OLEDB.4.0;data source=Northwind.mdb")
objAdapter = New OledbDataAdapter("SELECT CompanyName, City, Country FROM Customers", conn)
objAdapter.Fill(objDataSet, "myTable")
objTable=objDataSet.Tables("myTable")

outp = ""
c = chr(34)
for each x in objTable.Rows
if outp <> "" then outp = outp & ","
outp = outp & "{" & c & "Name"    & c & ":" & c & x("CompanyName") & c & ","
outp = outp &       c & "City"    & c & ":" & c & x("City")        & c & ","
outp = outp &       c & "Country" & c & ":" & c & x("Country")     & c & "}"
next

outp ="{" & c & "records" & c & ":[" & outp & "]}"
response.write(outp)
conn.close
%>

4. Server Code ASP.NET, Razor C# và SQL Lite

@{
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Response.AppendHeader("Content-type", "application/json")
var db = Database.Open("Northwind");
var query = db.Query("SELECT CompanyName, City, Country FROM Customers");
var outp =""
var c = chr(34)
}
@foreach(var row in query){
if (outp != "") {outp = outp + ","}
outp = outp + "{" + c + "Name"    + c + ":" + c + @row.CompanyName + c + ","
outp = outp +       c + "City"    + c + ":" + c + @row.City        + c + ","
outp = outp +       c + "Country" + c + ":" + c + @row.Country     + c + "}"
}
outp ="{" + c + "records" + c + ":[" + outp + "]}"
@outp

DOM HTML trong AngularJS

AngularJS có các chỉ thị để liên kết dữ liệu ứng dụng tới các thuộc tính của các phần tử HTML DOM.

Chỉ thị ng-disabled

Chỉ thị ng-disabled dùng để liên kết dữ liệu ứng dụng AngularJS tới thuộc tính disabled của các phần tử HTML.

Ví dụ

<div ng-app="" ng-init="mySwitch=true">

<p>
<button ng-disabled="mySwitch">Click Me!</button>
</p>

<p>
<input type="checkbox" ng-model="mySwitch">Button
</p>

<p>
{{ mySwitch }}
</p>

</div>

Giải thích:

Chỉ thị ng-disabled liên kết dữ liệu ứng dụng mySwitch tới thuộc tính disabled của nút lệnh (button).

Chỉ thị ng-model liên kết giá trị của phần tử checkbox tới giá trị của mySwitch.

Nếu giá trị của mySwitch có giá trị là true, thì button sẽ bị disabled:

<p>
<button disabled>Click Me!</button>
</p>

Nếu giá trị của mySwitch là false, thì button sẽ không bị disabled:

<p>
<button>Click Me!</button>
</p>

Chỉ thị ng-show

Chỉ thị ng-show dùng để hiện hoặc ẩn một phần tử HTML.

Ví dụ

<div ng-app="">

<p ng-show="true">I am visible.</p>

<p ng-show="false">I am not visible.</p>

</div>

Chỉ thị ng-show sẽ hiện hoặc ẩn phần tử HTML dựa trên value của ng-show.

Ta có thể sử dụng bất kỳ biểu thức nào để xác định giá trị true hay false:

Ví dụ

<div ng-app="" ng-init="hour=13">

<p ng-show="hour > 12">I am visible.</p>

</div>

Chỉ thị ng-hide

Chỉ thị ng-hide dùng để ẩn hoặc hiện phần tử HTML.

Ví dụ

<div ng-app="">

<p ng-hide="true">I am not visible.</p>

<p ng-hide="false">I am visible.</p>

</div>

Event trong AngularJS

AngularJS cũng có những chỉ thị sự kiện HTML của nó.

Các sự kiện trong AngularJS

Ta có thể thêm sự kiện AngularJS để "lắng nghe - listener" các phần tử HTML bằng cách sử dụng những chỉ thị sau đây:

  • ng-blur
  • ng-change
  • ng-click
  • ng-copy
  • ng-cut
  • ng-dblclick
  • ng-focus
  • ng-keydown
  • ng-keypress
  • ng-keyup
  • ng-mousedown
  • ng-mouseenter
  • ng-mouseleave
  • ng-mousemove
  • ng-mouseover
  • ng-mouseup
  • ng-paste

Chỉ thị sự kiện cho phép ta chạy các hàm AngularJS tại chính sự kiện của người dùng.

Mỗi sự kiện AngularJS sẽ không được viết đè vào sự kiện HTML, khi đó cả hai sự kiện sẽ phải được thực thi.

Sự kiện chuột

Sự kiện chuột xảy ra khi con trỏ di chuyển over một phần tử HTML theo thứ tự như sau:

  1. ng-mouseover
  2. ng-mouseenter
  3. ng-mousemove
  4. ng-mouseleave

Hoặc khi nhấn một nút nào đó của chuột vào phần tử theo trình tự:

  1. ng-mousedown
  2. ng-mouseup
  3. ng-click

Ta có thể thêm các sự kiện chuột trên bất kỳ phần tử HTML nào.

Ví dụ:

Tăng biến đếm khi di chuyển chuột over phần tử H1:

<div ng-app="myApp" ng-controller="myCtrl">

<h1 ng-mousemove="count = count + 1">Mouse over me!</h1>

<h2>{{ count }}</h2>

</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.count = 0;
});
</script>

Chỉ thị ng-click

Chỉ thị ng-click sẽ định nghĩa đoạn mã AngularJS mà sẽ được thực thi khi phần từ được nhấn (click).

Ví dụ:

<div ng-app="myApp" ng-controller="myCtrl">

<button ng-click="count = count + 1">Click me!</button>

<p>{{ count }}</p>

</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.count = 0;
});
</script>

Ta cũng có thể tham chiếu đến một hàm thay vì thực thi trực tiếp.

Ví dụ:

<div ng-app="myApp" ng-controller="myCtrl">

<button ng-click="myFunction()">Click me!</button>

<p>{{ count }}</p>

</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.count = 0;
    $scope.myFunction = function() {
        $scope.count++;
    }
});
</script>

Toggle, True/False

Nếu bạn hiện một phần mã lệnh HTML khi nhấn chuột và ẩn khi chuột lần nữa giống như dropdown thì ta sử dụng toggle:

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">

<button ng-click="myFunc()">Click Me!</button>

<div ng-show="showMe">
    <h1>Menu:</h1>
    <div>Pizza</div>
    <div>Pasta</div>
    <div>Pesce</div>
</div>

</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.showMe = false;
    $scope.myFunc = function() {
        $scope.showMe = !$scope.showMe;
    }
});
</script>

Biến showMe sẽ được khởi gán giá trị ban đầu là false.

Hàm myFunc thiết lập biến showMe ngược với giá trị biến đang chứa bằng cách sử dụng toán tử ! (not).

Đối tượng $event

Bạn có thể truyền đối tượng $event như là một đối số khi gọi hàm.

Đối tượng $event chứa đối tượng sự kiện của trình duyệt:

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">

<h1 ng-mousemove="myFunc($event)">Mouse Over Me!</h1>

<p>Coordinates: {{x + ', ' + y}}</p>

</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
    $scope.myFunc = function(myE) {
        $scope.x = myE.clientX;
        $scope.y = myE.clientY;
    }
});
</script>

Form trong AngularJS

Forms trong AngularJS cung cấp các control input để liên kết cũng như validate dữ liệu.

Control Input

Control input gồm những phần tử HTML sau:

  • Phần tửinput
  • Phần tử select
  • Phần tử button
  • Phần tử textarea

Liên kết dữ liệu

Control input cung cấp liên kết dữ liệu bằng cách sử dụng chỉ thị ng-model.

<input type="text" ng-model="firstname">

Ứng dụng lúc này sẽ có một thuộc tính tên firstname.

Chỉ thị ng-model sẽ liên kết controller input với phần còn lại của ứng dụng.

Thuộc tính firstname có thể được tham chiếu tới một controller:

Ví dụ

<script>
var app = angular.module('myApp', []);
app.controller('formCtrl'function($scope) {
    $scope.firstname = "John";
});
</script>

Nó cũng có thể được tham chiếu tới những nơi khác trong ứng dụng.

Ví dụ

<form>
First Name: <input type="text" ng-model="firstname">
</form>

<h1>You entered: {{firstname}}</h1>

Checkbox

Checkbox có giá trị true hoặc false. Ta áp dụng chỉ thị ng-model cho checkbox và sử dụng giá trị của nó trong ứng dụng.

Ví dụ

Hiện phần tử h1 nếu checkbox được check:

<form>
    Check to show a header:
    <input type="checkbox" ng-model="myVar">
</form>

<h1 ng-show="myVar">My Header</h1>

Radiobutton

Liên kết radio button tới ứng dụng bằng cách sử dụng chỉ thi ng-model.

Radio button với cùng chỉ thị ng-model có thể có những giá trị khác nhau, nhưng chỉ có thể chọn một trong các radio..

Ví dụ

Hiển thị một số text dựa trên giá trị của radio được chọn:

<form>
Pick a topic:
<input type="radio" ng-model="myVar" value="dogs">Dogs
<input type="radio" ng-model="myVar" value="tuts">Tutorials
<input type="radio" ng-model="myVar" value="cars">Cars
</form>

Giá trị của myVar sẽ có thể là dogstuts, hoặc cars.

Selectbox

Liên kết select box tới ứng dụng cũng bằng chỉ thi ng-model.

Thuộc tính được định nghĩa trong ng-model sẽ có giá trị của option được chọn trong selectbox.

Ví dụ

Hiển thị text dựa trên giá trị của option được chọn:

<form>
Select a topic:
<select ng-model="myVar">
    <option value="">
    <option value="dogs">Dogs
    <option value="tuts">Tutorials
    <option value="cars">Cars
</select>
</form>

Giá trị của myVar sẽ có thể là dogstuts, hoặc cars.

Ví dụ áp dụng

<div ng-app="myApp" ng-controller="formCtrl">
  <form novalidate>
    First Name:<br>
    <input type="text" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" ng-model="user.lastName">
    <br><br>
    <button ng-click="reset()">RESET</button>
  </form>
  <p>form = {{user}}</p>
  <p>master = {{master}}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('formCtrl'function($scope) {
    $scope.master = {firstName: "John", lastName: "Doe"};
    $scope.reset = function() {
        $scope.user = angular.copy($scope.master);
    };
    $scope.reset();
});
</script>

Thuộc tính novalidate là thuộc tính mới của HTML5. Nó không cho phép validate trên bất kỳ trình duyệt nào.

Giải thích ví dụ

Chỉ thị ng-app dùng để định nghĩa ứng dụng AngularJS.

Chỉ thị ng-controller dùng để định nghĩa controller của ứng dụng.

Chỉ thị ng-model liên kết hai phần tử input tới đối tượng user trong model.

Controller formCtrl thiết lập các giá trị ban đầu cho đối tượng master và định nghĩa phương thức reset().

Phương thức reset() thiết lập đối tượng user bằng đối tượng master.

Chỉ thị ng-click sẽ gọi phương thức reset() chỉ khi nút lệnh được nhấn.

Thuộc tính novalidate không cần thiết dùng đến trong ứng dụng, nhưng thường thị bạn sẽ sử dụng nó trong các form AngularJS để ghi đè chuẩn validate của HTML5.

Validate trong AngularJS

AngularJS có thể validate dữ liệu đã input.

Validate Form

AngularJS cung cấp việc validate form từ phía trình khách (client-side).

AngularJS tính toán trạng thái của form và các trường input (input, textarea, select) và nhắc người dùng về trạng thái hiện thời.

AngularJS cũng mang thông tin về việc chúng có được chạm, thay đổi hay không.

Ta có thể sử dụng các thuộc tính của chuẩn HTML5 để validate các input, hoặc ta cũng có thể tự tạo các hàm validate.

Validate phía client-side không thể bảo mật thông tin input, vì thế ta cần thực hiện thêm việc validate từ server.

Required

Thuộc tính required của HTML 5 dùng để check trống trường input.

Ví dụ

<form name="myForm">
<input name="myInput" ng-model="myInput" required>
</form>

<p>The input's valid state is:</p>
<h1>{{myForm.myInput.$valid}}</h1>

E-mail

Kiểu email dùng để yêu cầu rằng dữ liệu điền vào input phải là một e-mail.

Ví dụ

<form name="myForm">
<input name="myInput" ng-model="myInput" type="email">
</form>

<p>The input's valid state is:</p>
<h1>{{myForm.myInput.$valid}}</h1>

Trạng thái Form và trạng thái Input

AngularJS liên tục cập nhật trạng thái của cả form và các trường input.

Các trường input có các trạng thái như sau:

  • $untouched Trường không được chạm
  • $touched Trường được chạm
  • $pristine Trường không được thay đổi (modify)
  • $dirty Trường được thay đổi
  • $invalid Nội dung trường không hợp lệ.
  • $valid Nội dung trường hợp lệ.

Các trường trên đều là thuộc tính của trường input, ngoài ra bao gồm cả true và false.

Form có những trạng thái sau:

  • $pristine Không trường nào được thay đổi
  • $dirty Một hoặc nhiều trường được thay đổi
  • $invalid Nội dung form không hợp lệ
  • $valid Nội dung form hợp lệ
  • $submitted Form được submit

Tất cả các thuộc tính trên đều là của form, bao gồm cả true hoặc false.

Ta có thể sử dụng những trạng thái này để hiển thị thông báo có ý nghĩa đến người dùng. Ví dụ, nếu một trường được yêu cầu nhưng ta không điền dữ liệu thì ta cần đưa ra thông báo.

Ví dụ:

<input name="myName" ng-model="myName" required>
<span ng-show="myForm.myName.$touched && myForm.myName.$invalid">The name is required.</span>

CSS Class

AngularJS thêm các class của CSS vào form và các trường input phụ thuộc vào các trạng thái của chúng.

Những lớp được thêm vào hoặc bỏ đi từ trường input:

  • ng-untouched Trường không được chạm vào.
  • ng-touched Trường được chạm.
  • ng-pristine Trường không được thay đổi
  • ng-dirty Trường được thay đổi
  • ng-valid Trường nội dung hợp lệ
  • ng-invalid Trường nội dung không hợp lệ.
  • ng-valid-key Một key cho mỗi lần validate. Ví dụ: ng-valid-required hữu dụng khi có nhiều hơn một thứ gì đó phải được validate.
  • ng-invalid-key Ví dụ: ng-invalid-required

Các class sau được thêm hoặc bỏ đi từ form:

  • ng-pristine Không có trường nào được thay đổi
  • ng-dirty Một hoặc nhiều trường được thay đổi
  • ng-valid Nội dung form hợp lệ
  • ng-invalid Nội dung form không hợp lệ
  • ng-valid-key Một key cho mỗi lần validate. Ví dụ: ng-valid-required hữu dụng khi có nhiều hơn một trường phải được validate.
  • ng-invalid-key Ví dụ: ng-invalid-required

Các class đã được remove nếu giá trị mà chúng thể hiện là false.

Thêm các style cho những class này để cung cấp cho ứng dụng một giao diện đẹp hơn và trực quan hơn.

Ví dụ

<style>
input.ng-invalid {
    background-color: pink;
}
input.ng-valid {
    background-color: lightgreen;
}
</style>

Form cũng có thể được style.

Ví dụ

Nạp style cho form unmodified (pristine) và form modified:

<style>
form.ng-pristine {
    background-color: lightblue;
}
form.ng-dirty {
    background-color: pink;
}
</style>

Validate tùy chỉnh

Để tạo hàm validate tùy chỉnh thì ta cần thêm một chút công sức. Ta phải thêm một chỉ thị mới cho ứng dụng và đối phó với việc validate trong một hàm với các đối số được chỉ định.

Ví dụ

Tạo chỉ thị tùy chỉnh có chứa một hàm validate tùy chỉnh và tham chiếu tới nó bằng việc sử dụng my-directive.

Trường chỉ chứa dữ liệu hợp lệ khi có chứa ký tự 'e'.

<form name="myForm">
<input name="myInput" ng-model="myInput" required my-directive>
</form>

<script>
var app = angular.module('myApp', []);
app.directive('myDirective'function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attr, mCtrl) {
      function myValidation(value) {
        if (value.indexOf("e") > -1) {
          mCtrl.$setValidity('charE'true);
        } else {
          mCtrl.$setValidity('charE'false);
        }
        return value;
      }
      mCtrl.$parsers.push(myValidation);
    }
  };
});
</script>

Giải thích ví dụ:

Trong HTML, một chỉ thị mới sẽ được tham chiếu bằng cách sử dụng thuộc tính my-directive.

Trong JavaScript ta kích hoạt bằng cách thêm một chỉ thị mới có tên myDirective.

Cần nhớ rằng khi đặt tên của chỉ thị thì bạn phải sử dụng cách thực đặt tên kiểu camel (lạc đà), myDirective, nhưng khi gọi nó thì ta phải sử dụng ký tự nối -my-directive.

Sau đó trả về một đối tượng trong đó bạn chỉ định rằng ta yêu cầu ngModel, đó là ngModelController.

Tạo một hàm liên kết bao gồm một số đối số, trong đó đối số thứ tư mCtrl là ngModelController,

Sau đó chỉ định một hàm, trong trường hợp này hàm có tên là myValidation, hàm này có một đối số, đối số này là giá trị của phần tử input.

Kiểm tra xem giá trị nhập vào có chứa ký tự 'e' không, và thiết lập validate của model controller là true hoặc false.

Cuối cùng, mCtrl.$parsers.push(myValidation); sẽ thêm hàm myValidation vào một mảng các hàm khác, điều này sẽ được thực thi mỗi khi giá trị của input thay đổi.

Ví dụ về Validate

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>

<h2>Validation Example</h2>

<form  ng-app="myApp"  ng-controller="validateCtrl"
name="myForm" novalidate
>


<p>Username:<br>
  <input type="text" name="user" ng-model="user" required>
  <span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
  <span ng-show="myForm.user.$error.required">Username is required.</span>
  </span>
</p>

<p>Email:<br>
  <input type="email" name="email" ng-model="email" required>
  <span style="color:red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
  <span ng-show="myForm.email.$error.required">Email is required.</span>
  <span ng-show="myForm.email.$error.email">Invalid email address.</span>
  </span>
</p>

<p>
  <input type="submit"
  ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
  myForm.email.$dirty && myForm.email.$invalid"
>

</p>

</form>

<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl'function($scope) {
    $scope.user = 'John Doe';
    $scope.email = 'john.doe@gmail.com';
});
</script>

</body>
</html>

Thuộc tính novalidate dùng để disable việc validate form.

Giải thích ví dụ

Chỉ thị AngularJS ng-model sẽ liên kết các phần tử input tới model.

Đối tượng model có hai thuộc tính: user và email.

Vì chỉ thị ng-show, nên các thẻ <span> với color:red chỉ được hiển thị khi người dùng hoặc email là $dirty và $invalid.

Nguồn: https://www.w3schools.com/angular/angular_validation.asp

API trong AngularJS

API là các ký tự viết tắt của Application Programming Interface (dịch nôm na là: Giao diện Lập trình Ứng dụng).

Global API trong AngularJS

Global API trong AngularJS là một tập các hàm JavaScript global để giải quyết các công việc phổ biến như:

  • So sánh đối tượng
  • Xem (iterating) các đối tượng
  • Chuyển đổi dữ liệu

Các hàm Global API được truy cập bằng cách sử dụng các đối tượng angular.

Dưới đây là danh sách một số hàm API phổ biến:

API Mô tả
angular.lowercase() Chuyển chuỗi thành chữ thường
angular.uppercase() Chuyển chuỗi thành chữ hoa
angular.isString() Trả về true nếu tham chiếu là chuỗi
angular.isNumber() Trả về true nếu tham chiếu là số

angular.lowercase()

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.lowercase($scope.x1);
});
</script>

angular.uppercase()

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
$scope.x1 = "John";
$scope.x2 = angular.uppercase($scope.x1);
});
</script>

angular.isString()

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.isString($scope.x1);
});
</script>

angular.isNumber()

Ví dụ

<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('myCtrl'function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.isNumber($scope.x1);
});
</script>

Nguồn: https://www.w3schools.com/angular/angular_api.asp 

Include trong AngularJS

AngularJS cho phép ta đưa vào (include) HTML từ một file khác bằng cách sử dụng chỉ thị ng-include.

Ví dụ

<body ng-app="">

<div ng-include="'myFile.htm'"></div>

</body>

Include code của AngularJS

Bản thân các HTML ta cũng có thể đưa vào chỉ thị ng-include và có thể chứa code của AngularJS.

myTable.htm:

<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>

Khi đưa file "myTable.htm" vào trang web thì tất cả các code của AngularJS đều được thực thi ngay cả khi có code đó nằm trong file được đưa vào.

Ví dụ:

<body>

<div ng-app="myApp" ng-controller="customersCtrl"> 
  <div ng-include="'myTable.htm'"></div>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl'function($scope, $http) {
    $http.get("customers.php").then(function (response) {
        $scope.names = response.data.records;
    });
});
</script>

</body>

Include thông qua các domain (tên miền)

Mặc định thì chỉ thị ng-include sẽ không cho phép bạn include các file từ các domain khác.

Để include các file từ một domain khác thì ta có thể thêm một danh sách trắng (whitelist) các file và/hoặc các domain hợp lệ trong hàm cấu hình của ứng dụng.

Ví dụ:

<body ng-app="myApp">

<div ng-include="'https://tryit.v1study.com/angular_include.php'"></div>

<script>
var app = angular.module('myApp', [])
app.config(function($sceDelegateProvider) {
    $sceDelegateProvider.resourceUrlWhitelist([
        'http://tryit.v1study.com/**'
    ]);
});
</script>

</body>

Hãy chắc chắn rằng server đích sẽ cho phép truy cập thông qua file domain.

Nguồn: https://www.w3schools.com/angular/angular_includes.asp 

Animation trong AngularJS

AngularJS cũng cung cấp khả năng animation với sự trợ giúp từ CSS.

Animation là gì?

Animation ở đây là sự dịch chuyển của phần tử HTML tạo lên hiệu ứng di chuyển giả tưởng.

Ví dụ

<body ng-app="ngAnimate">

Hide the DIV: <input type="checkbox" ng-model="myCheck">

<div ng-hide="myCheck"></div>

</body>

Không nên lạm dụng animation trong ứng dụng, chỉ nên sử dụng khi cần thiết để ứng dụng dể hiểu hơn.

Cách tạo animation

Trước tiên ta sử dụng thư viện Animate của AngularJS:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-animate.js"></script>


Sau đó ta phải tham chiếu tới module ngAnimate trong ứng dụng:

<body ng-app="ngAnimate">

Hoặc nếu ứng dụng của ta đã có một tên thì ta thêm ngAnimate như là một phụ thuộc trong module ứng dụng.

Ví dụ

<body ng-app="myApp">

<h1>Hide the DIV: <input type="checkbox" ng-model="myCheck"></h1>

<div ng-hide="myCheck"></div>

<script>
var app = angular.module('myApp', ['ngAnimate']);
</script>

ngAnimate sẽ làm gì?

Module ngAnimate sẽ thêm và xóa các class của CSS.

Module ngAnimate không làm các phần tử HTML hoạt động được, nhưng khi nó nhận diện được các sự kiện nhât định như ẩn hoặc hiện phần tử HTML, thì phần tử đó sẽ lấy một số class đã được định nghĩa từ trước để có thể thực hiện được hiệu ứng animate.

Các chỉ thị của AngularJS mà có thể thêm/xóa các class là:

  • ng-show
  • ng-hide
  • ng-class
  • ng-view
  • ng-include
  • ng-repeat
  • ng-if
  • ng-switch

Các chỉ thị ng-show và ng-hide sẽ thêm hoặc xóa một giá trị class ng-hide.

Các chỉ thị khác sẽ thêm giá trị class ng-enter khi chúng được đưa vào DOM, và thêm thuộc tính ng-leave khi chúng được xóa khỏi DOM.

Chỉ thị ng-repeat cũng thêm giá trị class ng-move khi phần tử HTML thay đổi vị trí.

Mặt khác, trong quá trình thực thi animation thì phần tử HTML sẽ có một tập các giá trị class, và tập này sẽ bị xóa khi animation kết thúc. Ví dụ, chỉ thị ng-hide sẽ thêm những giá trị class sau đây:

  • ng-animate
  • ng-hide-animate
  • ng-hide-add (nếu phần tử sẽ ẩn)
  • ng-hide-remove (nếu phần tử sẽ hiện)
  • ng-hide-add-active (nếu phần tử sẽ ẩn)
  • ng-hide-remove-active (nếu phần tử sẽ hiện)

Animation sử dụng CSS

Ta có thể sử dụng transition hoặc animation của CSS để tạo animate cho các phần tử HTML. This tutorial will show you both.

 

CSS Transition

CSS transition cho phép ta thay đổi các giá trị thuộc tính CSS một cách mượt mà.

Ví dụ

<style>
div {
    transition: all linear 0.5s;
    background-color: lightblue;
    height: 100px;

}
.ng-hide {
    height: 0;
}

</style>

CSS Animation

CSS Animation cũng cho phép bạn thay đối các giá trị thuộc tính CSS một cách mượt mà.

Ví dụ

Khi phần tử <div> lấy class .ng-hide thì animation myChange sẽ chạy một cách mượt mà từ 100px tới 0.

<style>
@keyframes myChange {
    from {
        height: 100px;
    
} to {
        height: 0;
    
}
}
div {
    height: 100px;
    background-color: lightblue;

}
div.ng-hide {
    animation: 0.5s myChange;
}

</style>

Routing trong AngularJS

Module ngRoute sẽ giúp cho ứng dụng của ta trở thành một trang ứng dụng duy nhất.

Routing trong AngularJS là gì?

Nếu bạn muốn điều hướng tới các trang khác nhau trong ứng dụng nhưng bạn chỉ muốn ứng dụng là một Trang Ứng dụng Duy nhất (Single Page Application - SPA) mà không phải load lại trang thì bạn có thể sử dụng module ngRoute.

Module ngRoute sẽ định tuyến (route) ứng dụng của ta tới các trang khác nhau mà không cần tải lại toàn bộ ứng dụng.

Ví dụ

<body ng-app="myApp">

<p><a href="#/!">Main</a></p>

<a href="#!red">Red</a>
<a href="#!green">Green</a>
<a href="#!blue">Blue</a>

<div ng-view></div>

<script>
var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/red", {
        templateUrl : "red.htm"
    })
    .when("/green", {
        templateUrl : "green.htm"
    })
    .when("/blue", {
        templateUrl : "blue.htm"
    });
});
</script>
</body>

Áp dụng

Để áp dụng routing thì ta đưa module AngularJS Route vào như sau:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>

Sau đó bạn phải thêm ngRoute như là một phụ thuộc của module ứng dụng:

var app = angular.module("myApp", ["ngRoute"]);

Bây giờ ta đã có thể truy cập được module route thông qua $routeProvider.

Ta sử dụng $routeProvider để cấu hình các route khác nhau trong ứng dụng:

app.config(function($routeProvider) {
  $routeProvider
  .when("/", {
    templateUrl : "main.htm"
  })
  .when("/red", {
    templateUrl : "red.htm"
  })
  .when("/green", {
    templateUrl : "green.htm"
  })
  .when("/blue", {
    templateUrl : "blue.htm"
  });
});

Đích đến của route

Ứng dụng của ta cần phải có một bộ chứa để đấy nội dung thông qua routing.

Bộ chứa này là chỉ thị ng-view.

Có ba cách khác nhau để đưa chỉ thị ng-view vào ứng dụng của ta thông qua ba ví dụ sau đây.

Ví dụ 1

<div ng-view></div>

Ví dụ 2

<ng-view></ng-view>

Ví dụ 3

<div class="ng-view"></div>

Ứng dụng chỉ có thể có một chỉ thị ng-view và nó sẽ thay cho tất cả các view được cung cấp bởi route.

$routeProvider

Với $routeProvider ta cho thể chỉ định trang nào được hiển thị khi người dùng nhấn link.

Ví dụ

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/london", {
        templateUrl : "london.htm"
    })
    .when("/paris", {
        templateUrl : "paris.htm"
    });
});

Để định nghĩa $routeProvider thì ta sử dụng phương thức config của ứng dụng. Những gì đã được đăng ký trong phương thức config sẽ được thực hiện khi ứng dụng được load.

Controller

Với $routeProvider bạn cũng có thể chỉ định controller cho mỗi "view".

Ví dụ

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        templateUrl : "main.htm"
    })
    .when("/london", {
        templateUrl : "london.htm",
        controller : "londonCtrl"
    })
    .when("/paris", {
        templateUrl : "paris.htm",
        controller : "parisCtrl"
    });
});
app.controller("londonCtrl"function ($scope) {
    $scope.msg = "I love London";
});
app.controller("parisCtrl"function ($scope) {
    $scope.msg = "I love Paris";
});

"london.htm" và "paris.htm" là những file HTML, và bạn có thể thêm các biểu thức AngularJS vào giống như những phần HTML khác của ứng dụng AngularJS.

Chẳng hạn các file sẽ như thế này:

london.htm

<h1>London</h1>
<h3>London is the capital city of England.</h3>
<p>It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.</p>
<p>{{msg}}</p>

paris.htm

<h1>Paris</h1>
<h3>Paris is the capital city of France.</h3>
<p>The Paris area is one of the largest population centers in Europe, with more than 12 million inhabitants.</p>
<p>{{msg}}</p>

Template

Trong những ví dụ trước ta từng sử dụng thuộc tính templateUrl trong phương thức $routeProvider.when.

Bạn cũng có thể sử dụng thuộc tính template để cho phép viết HTML trực tiếp trong giá trị property và không tham chiếu tới trang web.

Ví dụ

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
    $routeProvider
    .when("/", {
        template : "<h1>Main</h1><p>Click on the links to change this content</p>"
    })
    .when("/banana", {
        template : "<h1>Banana</h1><p>Bananas contain around 75% water.</p>"
    })
    .when("/tomato", {
        template : "<h1>Tomato</h1><p>Tomatoes contain around 95% water.</p>"
    });
});

Phương thức otherwise()

Trong những ví dụ trên ta đã sử dụng phương thức when của $routeProvider.

Bạn cũng có thể sử dụng phương thức otherwise là phương thức mặc định khi không có sự tương thích (match).

Ví dụ

Nếu "Banana" hoặc "Tomato" không được nhấn thì phương thức otherwise() sẽ được kích hoạt.

var app = angular.module("myApp", ["ngRoute"]);
app.config(function($routeProvider) {
   $routeProvider
    .when("/banana", {
        template : "<h1>Banana</h1><p>Bananas contain around 75% water.</p>"
    })
    .when("/tomato", {
        template : "<h1>Tomato</h1><p>Tomatoes contain around 95% water.</p>"
    })
    .otherwise({
        template : "<h1>None</h1><p>Nothing has been selected</p>"
    });
});

Chỉ thị, Filter, Property, API

Chỉ thị trong AngularJS

Chỉ thị Mô tả
ng-app Định nghĩa phần tử gốc của ứng dụng
ng-bind Liên kết nội dụng của phần tử HTML với dữ liệu ứng dụng.
ng-bind-html Liên kết nội dung nằm trong thẻ HTML hoàn chỉnh (qua thuộc tính innerHTML) tới dữ liệu ứng dụng, đồng thời loại bỏ đoạn mã nguy hiểm từ chuỗi HTML.
ng-bind-template Chỉ định nội dung của văn bản cần được thay thế bằng một template.
ng-blur Chỉ định hành vi trên sự kiện blur.
ng-change Chỉ định một biểu thức lượng giá khi người dùng thay đổi nội dung.
ng-checked Chỉ định phần tử được check hoặc không.
ng-class Chỉ định class của CSS trong phần tử HTML.
ng-class-even Tương tự như ng-class nhưng sẽ chỉ chịu ảnh hưởng trên các hàng chẵn.
ng-class-odd Tương tự như ng-class nhưng sẽ chỉ chịu ảnh hưởng trên các hàng lẻ.
ng-click Chỉ định một biểu thức thực thi khi phần tử được click.
ng-cloak Ngăn chặn hiệu ứng nhấp nháy khi ứng dụng đang được tải.
ng-controller Định nghĩa đối tượng controller cho ứng dụng.
ng-copy Chỉ định hành vi trên các sự kiện copy.
ng-csp Thay đổi chính sách bảo mật nội dung.
ng-cut Chỉ định hành vi cho sự kiện cut.
ng-dblclick Chỉ định hành vi cho sự kiện double-click.
ng-disabled Chỉ định một sự kiện là disabled hoặc không.
ng-focus Chỉ định hành vi cho sự kiện focus.
ng-form Chỉ định form HTML để thừa kế từ các control.
ng-hide Ẩn hoặc hiện các phần tử HTML.
ng-href Chỉ định một url cho phần tử <a>.
ng-if Xóa phần tử HTML nếu điều kiện sai.
ng-include Đưa HTML vào ứng dụng.
ng-init Định nghĩa các giá trị khởi tạo cho application.
ng-jq Yêu cầu ứng dụng phải sử dụng thư viện jQuery.
ng-keydown Chỉ định hành vi cho sự kiện keydown.
ng-keypress Chỉ định hành vi cho sự kiện keypress.
ng-keyup Chỉ định hành vi cho sự kiện keyup.
ng-list Chuyển văn bản vào list (chẳng hạn như mảng).
ng-maxlength Chỉ định số lượng ký tự lớn nhất được phép trong trường input.
ng-minlength Chỉ định số lượng ký tự tối thiểu trong trường input.
ng-model Liên kết giá trị của các control HTML vào dữ liệu ứng dụng.
ng-model-options Chỉ định cách các update trong model được thực hiện.
ng-mousedown Chỉ định hành vi cho sự kiện mousedown.
ng-mouseenter Chỉ định hành vi cho sự kiện mouseenter.
ng-mouseleave Chỉ định hành vi cho sự kiện mouseleave.
ng-mousemove Chỉ định hành vi cho sự kiện mousemove.
ng-mouseover Chỉ định hành vi cho sự kiện mouseover.
ng-mouseup Chỉ định hành vi cho sự kiện mouseup.
ng-non-bindable Chỉ định rằng không có liên kết dữ liệu nào cho phần tử hiện thời hay con của phần tử hiện thời.
ng-open Chỉ định thuộc tính open của một phần tử.
ng-options Chỉ định các <option> trong <select> hoặc <datalist>.
ng-paste Chỉ định hành vi cho sự kiện paste.
ng-pluralize Chỉ định một thông báo để hiển thị theo quy tắc nội địa hóa en-us.
ng-readonly Chỉ định thuộc tính readonly cho phần tử.
ng-repeat Định nghĩa một template cho mỗi dữ liệu trong collection.
ng-required Chỉ định thuộc tính required của một phần tử.
ng-selected Chỉ định thuộc tính selected của phần tử.
ng-show Hiện hoặc ẩn phần tử HTML.
ng-src Chỉ định thuộc tính src cho phần tử <img>.
ng-srcset Chỉ định thuộc tính srcset cho phần tử <img>.
ng-style Chỉ định thuộc tính style cho phần tử.
ng-submit Chỉ định biểu thức để chạy cho sự kiện onsubmit.
ng-switch Chỉ định điều kiện mà sẽ được dùng để hiện/ẩn các phần tử con.
ng-transclude Chỉ định một điểm để chèn phần tử nhúng.
ng-value Chỉ định giá trị của một phần tử input.


Các chỉ thị AngularJS trên các phần tử HTML

AngularJS đã sửa các hành vi mặc định của một số phần tử HTML như sau:

Phần tử Mô tả
a AngularJS thay đổi các hành vi mặc định của phần tử <a>.
form AngularJS thay đổi các hành vi mặc định của phần tử <form>.
input AngularJS thay đổi các hành vi mặc định của phần tử <input>.
script AngularJS thay đổi các hành vi mặc định của phần tử <script>.
select AngularJS thay đổi các hành vi mặc định của phần tử <select>.
textarea AngularJS thay đổi các hành vi mặc định của phần tử <textarea>.

Các filter trong AngularJS

Filter Mô tả
currency Định dạng một số thành dạng tiền tệ.
date Chuyển một ngày sang định dạng được chỉ định.
filter Chọn một số phần tử trong mảng.
json Chuyển một đối tượng sang dạng JSON.
limitTo Giới hạn một mảng, hoặc một chuỗi vào trong một số lượng các phần tử/ký tự được chỉ định.
lowercase Chuyển chuỗi sang dạng chữ thường.
number Chuyển số sang chuỗi.
orderBy Sắp xếp mộng mảng thông qua biểu thức.
uppercase Chuyển chuỗi sang dạng chữ hoa.

Xin xem chi tiết về filter tại bài viết Filter trong Angular.

Các thuộc tính validate trong AngularJS

  • $dirty
  • $invalid
  • $error

Xin xem chi tiết về validate tại bài viết Validate trong AngularJS.

Global API trong AngularJS

Chuyển đổi

API Mô tả
angular.lowercase() Chuyển chuỗi thành chữ thường
angular.uppercase() Chuyển chuỗi thành chữ hoa
angular.copy() Tạo một bản copy deep cho một đối tượng hoặc một mảng
angular.forEach() Thực thi một chức năng cho mỗi phần tử trong một mảng hoặc đối tượng.

So sánh

API Mô tả
angular.isArray() Trả về true nếu tham chiếu là một mảng
angular.isDate() Trả về true nếu tham chiếu là một date
angular.isDefined() Trả về true nếu tham chiếu được định nghĩa
angular.isElement() Trả về true nếu tham chiếu là một phần tử DOM
angular.isFunction() Trả về true nếu tham chiếu là một hàm (function)
angular.isNumber() Trả về true nếu tham chiếu là một number
angular.isObject() Trả về true nếu tham chiếu là một object
angular.isString() Trả về true nếu tham chiếu là một chuỗi
angular.isUndefined() Trả về true nếu tham chiếu không được định nghĩa
angular.equals() Trả về true nếu hai tham chiếu bằng nhau

JSON

API Mô tả
angular.fromJson() Lấy chuỗi JSON và trả về một đối tượng JavaScript
angular.toJson() Lấy đối tượng JavaScript và trả về chuỗi JSON

Cơ bản

API Mô tả
angular.bootstrap() Kích hoạt AngularJS theo cách thủ công
angular.element() Gộp một phần tử HTML như là một phần tử jQuery
angular.module() Tạo, đăng ký hoặc truy xuất một module AngularJS

Xin xem chi tiết về Global API tại bài viết API trong AngularJS.

Nguồn: https://www.w3schools.com/angular/angular_ref_directives.asp