+8

[AngularJS toàn tập] Phần 3 : Expression

[AngularJS toàn tập] Phần 3 : Expression

Khi bạn làm việc với AngularJS chắc chắn bạn sẽ nhiều làn sử dụng đến expression, vậy nó là gì? sử dụng như thế nào? hoạt động ra sao? Ở bài viết này mình sẽ chỉ ra cho bạn biết những điều đó.

angular ex.jpg

Expression là gì?

Expression hay còn gọi là biểu thức, được sử dụng rất rất nhiều trong ứng dụng AngularJS. Expression được dùng trong template, các thẻ đánh dấu, trong các directives. Nó được sử dụng để gắn kết các dữ liệu của ứng dụng ra thẻ HTML. Expression được viết trong dấu {{ expression }}. Cách hoạt động của expression khá giống với ng-bind directive. Về cơ bản thì các expression trong ứng dụng AngularJS là các javascript expression thuần túy và xuất kết quả là dữ liệu.

Ví dụ về sử dụng expression :

Sử dụng số

<p>Chi phí mượn sách: {{gia * soluong}}.000 VND</p>

Sử dụng đối tượng

<div ng-app ng-init="nhan_vien={ten:'Hoàng', ho: 'Phương'}">
    <p>Thông tin nhân viên</p>
    <p>Tên : {{nhan_vien.ten}}</p>
    <p>Họ : {{nhan_vien.ho}}</p>
</div>

Sử dụng chuỗi

<p>Xin chào bạn {{khach_hang.ho + " " + khach_hang.ten}}!</p>

Sử dụng mảng

<div ng-app ng-init="danh_sach_SV=['Hoàng', 'Hoa', 'Tuấn']">
    <p> Sinh viên 1: {{danh_sach_SV[0]}}</p>
    <p> Sinh viên 2: {{danh_sach_SV[1]}}</p>
    <p> Sinh viên 3: {{danh_sach_SV[2]}}</p>
</div>

còn với ng-bind directive

<div ng-app ng-init="danh_sach_SV=['Hoàng', 'Hoa', 'Tuấn']">
    <p> Sinh viên 1: <span ng-bind="danh_sach_SV[0]"></span></p>
    <p> Sinh viên 2: <span ng-bind="danh_sach_SV[0]"></span></p>
    <p> Sinh viên 3: <span ng-bind="danh_sach_SV[0]"></span></p>
</div>

Ví dụ kết hợp :

<html>
    <head>
        <meta charset="UTF-8">
        <title>Ví dụ về expression </title>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        </head>

    <body>
      <h1>Ứng dụng AngularJS</h1>
      <div ng-app="" ng-init="sinhvien={ho:'Nguyen Dinh',ten:'Huan',mssv:2122342}; diemthi=[8.5,8,7,7,5.0]; soluong=2;gia=40">
        <p>Sinh viên : {{sinhvien.ho + " " + sinhvien.ten}}</p>
        <p>MSSV: {{sinhvien.mssv}}</p>
        <p>Tien no sach thu vien: {{gia * soluong}}.000 VND</p>
        <p>Diem thi môn AngularJS: {{diemthi[3]}}</p>
      </div>
    </body>
</html>

Các bạn có thể xem demo tại đây. https://jsfiddle.net/SonCheDinh/96fsn6wa/

Trong angular JS thì khi bạn sử dụng cú pháp {{ }}, thì bạn đang thiết lập cơ chế $watch lên một expression. Như vậy thì hàm $watch sẽ theo dõi một thuộc tính trên $scope, và khi có bất cứ một thay đổi nào thì nó sẽ gọi chức năng tương ứng.

Ví dụ các expression hợp lệ trong Angular JS

Trong angularJS việc ước lượng các expression được thực hiện bằng cách tự động chạy dịch vụ $parse khi nó thực thi vòng lặp $digest. Và $parse chính là cơ chế mà AngularJS sử dụng để ước lượng expression.

AngularJS expression và Javascript expression

Về cơ bản thì Expression trong AngularJS gần giống với Javascript Expression. Tuy nhiên AngularJS có cơ chế riêng của mình để phân tích expression và tìm ra ngữ nghĩa riêng của nó. Các điểm khác biệt đó chính là :

  • Tất cả các expression trong Angular JS có quyeèn truy cập vào biến $scope cục bộ và được thực thi trong ngữ cảnh scope.
  • Thay vì phát sinh ra lỗi ReferenceError hay là TypeError như javascript thì các expression trong AngularJS không ném ra lỗi và trả lại giá trị undefined khi ước lượng với các giá trị null hay undefined.
  • AngularJS không cho phép các câu lệnh điều kiện (condition), điều kiện lặp (loop) hay các ngoại lệ (throw exceptions). (Ngoại trừ toán tử tam phân a ? b : c)
  • Angular JS cho phép expression sử dụng các $filter hoặc một chuỗi các filter để định dạng dữ liệu trước khi hiển thị.
  • Angular JS không cho phép tạo ra các biểu thức chính quy (regex) trong expression.

Danh sách các biểu thức có thể sử dụng trong AngularJS Exception

angular js exceptions.png

Một ví dụ nữa để hiểu rõ hơn về Angular JS exceptions

<html>
    <head>
        <meta charset="UTF-8">
        <title>Ví dụ về expression </title>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    </head>
    <body>
        <div ng-app="app" ng-controller="mainCtrl">
            <em> chỉ hiển thị được giá trị của var1, var3 </em>
            <p>giá trị var1: <b>{{var1 + y}}</b></p>
            <p>giá trị var2: <b>{{var2}}</b></p>
            <p>giá trị var3: <b>{{var3}}</b></p>
            <hr/>
            <em> với biến <b>y</b> chưa được khai báo, angular xem nó có giá trị là undefined </em>
            <p>value of var3 + y: <b>{{var3 + y}}</b></p>
            <p>y isUndefined: <b>{{checkUndefined(y)}}</b></p>
            <hr/>
            <em>Function trong controller có thể được gọi và trả lại giá trị đã được tính toán trong expression</em>
            <p>var2 isDefined (call function checkDefined()): <b>{{checkDefined(var2)}}</b></p>
            <p>Trả về giá trị của hàm "upperString()" : <b>{{upperString('hello world!')}}</b></p>
            <hr/>
            <em>Các toán tử</em>
            <p>var1 - var3 < 10 : <b>{{var1 - var3 < 10}}</b></p>
            <p>var3 === 10 : <b>{{var3 === 10}}</b></p>
            <p> 30 %(mod) 29 = <b>{{ var3 % 29 }}</b> </p>
            <em><b>Không</b> thể sử dụng toán tử ++, --. Bỏ comment để xem kết quả </em>
            <!-- <p> ++30 = {{++30}}</p> -->
            <hr/>
            <em>Toán tử tam nguyên</em>
            <p>var1 <b>{{var1>0?'greater than 0':'less than 0'}}</b> </p>
            <hr/>
            <em>Một số trường hợp không thể sử dụng(Bỏ comment để thấy kết quả)</em>
            <!-- If else -->
            <!-- <p> {{ if(var1>0)var1 else var3  }} </p> -->

            <!-- loops 
            <!--<p> {{while(var1>0){var1=var1-1;}}} </p>-->

            <!--Expression inside expression -->
            <!--<p> {{var1 + {{var2}}}}-->
        </div>
    </body>

    <script language="javascript">
        angular.module('app', [])
        .controller('mainCtrl', function($scope){
            //chỉ có các biến được khai báo trong scope mới có thể truy cập được
            var var2 = 20;
            $scope.var1 = 10;
            $scope.var3 = 30;

            $scope.upperString = function(str) {
                return angular.uppercase(str);
            }
            $scope.checkDefined = function(val) {
                return angular.isDefined(val);
            }
            $scope.checkUndefined = function(val) {
                return angular.isUndefined(val);
            }
        });
    </script>
</html>

Các bạn có thể xem demo tại đây http://jsfiddle.net/SonCheDinh/3wyut7r9/

Tính năng one-time binding

Từ phiên bản 1.3 trở đi thì AngularJS đã cung cấp tính năng one-time binding (gắn kết dữ liệu một lần) bằng cách sử dụng dấu :: trước exception như sau {{ ::expression }} . Với tính năng này thì expression chỉ được nội suy một lần duy nhất, sau đó nó sẽ không được theo dõi nữa. Điều này giúp giải phóng tài nguyên khi việc gắn kết dữ liệu đã ổn định. Việc giảm theo dõi một số lượng các biểu thức giúp cho các vòng lặp thực thi nhanh hơn, cho phép nhiều thông tin sẽ được hiển thị cùng lúc.

Ví dụ về tính năng one-time binding

<html>
    <head>
        <meta charset="UTF-8">
        <title>Ví dụ về one-time binding </title>
        <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
    </head>
    <body>
        <div ng-app="app" ng-controller="MainCtrl">
            <button ng-click="clickMe()">Click Me</button>
            <p>One-time binding: {{ ::student }}</p>
            <p>Normal binding: {{ student }}</p>
        </div>
    </body>
    <script language="javascript">
    angular.module("app", [])
    .controller("MainCtrl", function($scope){
        var counter = 0;
        var students= ['Hoang', 'Lien', 'Huong', 'Tuan', 'Tu'];
        $scope.clickMe = function() {
            $scope.student = students[counter % students.length];
            counter++;
        }
    });
    </script>
</html>

Demo tại đây https://jsfiddle.net/SonCheDinh/0k2njcbr/

Bài viết về AngularJS expression của mình đến đây là hết, hẹn gặp các bạn ở blog sau.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí