ANGULARJS CĂN BẢN PHẦN I
AngularJS là một framework Javascript mạnh mẽ, được nhúng vào HTML page bằng thẻ Script. AngularJS mở rộng thêm thuộc tính của HTML với các (chỉ thị, lệnh) Directives , và liên kết dữ liệu đến HTML với các (biểu thức) Expressions nhằm giảm bớt quá trình phát triển ứng dụng web. Về lịch sử hình ...
AngularJS là một framework Javascript mạnh mẽ, được nhúng vào HTML page bằng thẻ Script. AngularJS mở rộng thêm thuộc tính của HTML với các (chỉ thị, lệnh) Directives , và liên kết dữ liệu đến HTML với các (biểu thức) Expressions nhằm giảm bớt quá trình phát triển ứng dụng web.
Về lịch sử hình thành, dự án AngularJS được bắt đầu từ năm 2009, do lập trình viên Misko Hevery tại Google viết ra. Misko và nhóm lúc này đang tham gia vào một dự án của Google tên là Google Feedback. Với AngularJS, Misko đã rút ngắn số dòng code front-end từ 17000 dòng còn chỉ khoảng 1500. Với sự thành công đó, đội ngũ của dự án Google Feedback quyết định phát triển AngularJS theo hướng mã nguồn mở.
Một số tính năng chính của AngularJS:
- Cách liên kết dữ liệu hai luồng của AngularJS là khả năng thay đổi giá trị thuộc tính của đối tượng, đồng thời phản ánh lên giao diện người dùng ngay tại thời điểm đó và ngược lại.
- Mở rộng thêm thuộc tính của HTML.
- Template chỉ cần HTML.
- Tổ chức code thành các modules, dễ dàng quản lý và dùng lại.
Có hai cách để chèn AngularJS vào ứng dụng.
- Cách 1: Truy cập vào trang web https://angularjs.org hoặc https://github.com/angular/angular.js và tải về bản AngularJS mới nhất. Bản hiện tại mới nhất là 1.5.8. Sau đó nhúng vào ứng dụng qua thẻ script.
<script src="angular.min.js"></script>
- Cách 2: Sử dụng trực tiếp phiên bản nén của AngularJS có sẵn trên server Google, cách này tiết kiệm băng thông cho trang web và AngularJS sẽ tải nhanh hơn nếu máy đã cache AngularJS, nhưng hiển nhiên máy tính phải được kết nối internet.
= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js", "data-turbolinks-track" => true
Xây dựng một ứng dụng đơn giản
<div ng-app class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive" %> <p>Hello {{'World' + '!'}}</p> </div>
Kết quả:
Trong quá trình xây dựng hệ thống file HTML đôi khi trở nên quá phức tạp gây khó khăn cho việc quản lý để giải vấn đề này ta cần chia file HTML lớn thành các phần khác nhau, AngularJS cung cấp một giải pháp khá hữu ích là template. Có thể hiểu đơn giản AngularTemplate là static DOM chứa HTML, Css và các thuộc tính riêng của Angular.
Có hai cách để tạo một template.
- Cách 1: Sử dụng một file bên ngoài làm template cho file chính.
- Cách 2: Tích hợp thẳng template vào file thông qua thẻ script với type là text/ng-template.
Ví dụ
<div ng-app="ExampleModule" class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive", style: "margin-bottom: 20px;" %> <div ng-controller="ExampleCtrl"> <input type="text" ng-model="name" class="form-control"> <div ng-include src="template_name"></div> </div> <script type="text/ng-template" id="template-demo"> <h3>Hello, {{name}}!</h3> </script> </div> <script type="text/javascript"> var app = angular.module("ExampleModule", []); app.controller("ExampleCtrl", function($scope) { $scope.template_name = "template-demo"; $scope.name = "World"; }); </script>
Kết quả:
Một module AngularJS định nghĩa một ứng dụng là chứa các thành phần khác nhau của ứng dụng. Việc chia nhỏ ứng dụng sẽ có những lợi ích sau:
- Dễ dàng hơn cho việc quản lý và khai báo ứng dụng cũng như kiểu tra lại sau này.
- Khả năng tái sử dụng được các thành phần trùng lặp.
- Nạp từng phần ứng dụng sẽ nhanh hơn là buộc phải nạp toàn bộ ứng dụng vào rồi mới chạy.
Ở ví dụ trên chúng ta có thể viết như sau:
<div ng-app="ExampleModule" class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive", style: "margin-bottom: 20px;" %> <div ng-controller="ExampleCtrl"> <input type="text" ng-model="name" class="form-control"> <div ng-include src="template_name"></div> </div> <script type="text/ng-template" id="template-demo"> <h3>Hello, {{name}}!</h3> </script> </div> <script type="text/javascript"> <%= render "my_app.js" %> </script> <script type="text/javascript"> <%= render "my_controller.js" %> </script>
Trong đó:
My_app:
var app = angular.module("ExampleModule", []);
My_controller:
app.controller("ExampleCtrl", function($scope) { $scope.template_name = "template-demo"; $scope.name = "World"; });
- ng-app="myModule": Khai báo một angular app là myModule
- angular.module() là hàm khai báo cho module.
- Cặp dấu ngoặc [] chính là mảng các module sẽ được nạp chung vào để chạy chung với ứng dụng (module chính được khai báo trong ng-app). Ví dụ:
var app = angular.module("myModule", ["ngRoute", "ngBootstrap"]);
Scope là một đối tượng có nhiệm vụ giao tiếp dữ liệu giữa controller và view của ứng dụng. Có thể hiểu đơn giản là nếu thêm dữ liệu cho scope ở controller thì bên view có khai báo theo đúng quy tắc thì sẽ tự động gán thông tin vào đúng vị trí đó.
Xét ví dụ dưới để hiểu rõ hơn.
<div ng-app="ExampleModule" class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive", style: "margin-bottom: 20px;" %> <div ng-controller="ExampleCtrl"> Your Name: <input type="text" ng-model="name" class="form-control"> <button ng-click="welcom()" class="btn btn-success" style="margin-top: 10px;">Submit</button> <h3>{{your_name}}!</h3> </div> </div> <script type="text/javascript"> angular.module("ExampleModule", []) .controller("ExampleCtrl", ["$scope", function($scope) { $scope.welcom = function() { $scope.your_name = "Xin chào " + $scope.name + "!"; }; }]); </script>
Kết quả
Trong đó:
- ng-click="welcom()": khai báo một action khi click vào button sẽ gọi đến hàm welcom() được định nghĩa trong $$cope ở controller.
- Trong ví dụ trên cũng có thể thấy được cú pháp gán giá trị cho view ở biểu thức {{your_name}}
$scope.welcom = function() { $scope.your_name = "Xin chào " + $scope.name + "!"; };
đồng thời cú pháp lấy dữ liệu của model với key được khai báo
Model: <input type="text" ng-model="name" class="form-control"> Lấy giá trị: $scope.name
Phạm vi ảnh hưởng của $$cope
Phạm vi ảnh hưởng của scope giới hạn trong khai báo của từng controller nghĩa là với những controller khác nhau thì scope sẽ tự động nhận diện giá trị tương ứng của controller đó.
Xét ví dụ sau để hiểu rõ:
<div ng-app="ExampleModule" class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive", style: "margin-bottom: 20px;" %> <div ng-controller="GreetController"> Hello {{name}}! </div> <div ng-controller="ListController"> Hello {{name}}! </div> </div> <script type="text/javascript"> angular.module("ExampleModule", []) .controller("GreetController", function ($scope){ $scope.name = "Nguyễn Văn A"; }) .controller("ListController", function ($scope){ $scope.name = "Học Lập Trình Online"; }); </script>
Kết quả:
Trong đó đoạn code dưới đây là khai báo view thứ nhất:
<div ng-controller="GreetController"> Hello {{name}}! </div>
Tương ứng với controller khai báo trong view là đoạn JS:
.controller('GreetController', function ($scope){ $scope.name = 'Nguyễn Văn Cường'; })
Đoạn code sau khai bái view thứ hai:
<div ng-controller="ListController"> Hello {{name}}! </div>
Tương ứng với controller khai báo trong view là đoạn JS:
.controller('ListController', function ($scope){ $scope.name = 'Học Lập Trình Online'; });
Tìm hiểu $$ootScope
Cùng xét tiếp ví dụ trên, bây giờ sẽ đổi một chút như phía dưới.
<script type="text/javascript"> angular.module("ExampleModule", []) .controller('GreetController', function ($scope, $rootScope){ $rootScope.name = 'Học Lập'; }) .controller('ListController', function ($scope){ }); </script>
Kết quả
Có thể thấy ở controller thứ nhất có thêm tham số rootScope và ở controller thứ hai không xử lý gì cả tuy vậy khi chạy giá trị {{name}} ở controller thứ hai vẫn được tạo. Lý do ở đây là tham số rootScope có bậc cao nhất sẽ bao quát hết các scope bên trong nó, điều này không giống với scope chỉ ảnh hưởng trong phạm vi của controller.
$$cope lồng nhau
Thay đổi một chút ví dụ trên như sau:
<div ng-app="ExampleModule" class="container" style="padding-top: 40px; text-align: center;"> <%= image_tag "angularjs.jpg", class: "img-responsive", style: "margin-bottom: 20px;" %> <div class="show-scope-demo"> <div ng-controller="TopController"> <div ng-controller="GreetController"> Hello {{name}}! </div> <div ng-controller="ListController"> Hello {{name}}! </div> {{name}} </div> </div> </div> <script type="text/javascript"> angular.module("ExampleModule", []) .controller("TopController", function ($scope){ $scope.name = "demo"; }) .controller("GreetController", function ($scope){ }) .controller("ListController", function ($scope){ }); </script>
Kết quả
Hello demo! Hello demo! demo
AngularJS chạy theo nguyên tắc controller ngoài cùng sẽ chạy trước do vậy tất cả các {{name}} sẽ có giá trị là "demo" sau đó các controller bên trong sẽ ghi đè lại giá trị của {{name}} nếu được khai báo.
Do bài viết đã khá dài nên mình tạm thời xin dừng ở đây. Các bạn cũng đã cơ bản hiểu được AngularJS là gì? làm được gì? cách thức hoạt động ra sao. Trong phần tiếp theo xin tiếp tục giới thiệu những phần tiếp sẽ thấy rõ hơn sức mạnh của AngularJS.
Những phần có thể giới thiệu trong phần sau:
- Model
- Controller
- Expression (biểu thức)
- Filters
- Directives
- ...