Tìm hiểu AngularJS - Controller (P3)

  • Như đã đề cập ở bài lần trước (Tìm hiểu AngularJS - Expressions, Directives). Bài này chúng ta sẽ cùng nhau tìm hiều về Controller trong AngularJS, hay nói cách khác nó chính là ng-controller directive. Ngoài ra bài này mình cũng có đề cập đến một khái niệm mới nữa là scope.

I. Scope

1. Khái niệm

  • $scope là một object (đối tượng) có nhiệm vụ giao tiếp dữ liệu giữa controller và view của ứng dụng. Hay nói cách khác nó chính là cầu nối giữa controller và view. Bản thân nó chứa các domain của scope được controller gắn các giá trị vào các thuộc tính và truyền ra view.

2. Ví dụ

  • Ví dụ in ra câu thông báo khi click vào button:
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf8">
        <title>AngularJS Scope Object</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script>
            angular.module('scopeExample', [])
            .controller('MyController', ['$scope', function($scope)
            {
                $scope.sayHello = function() {
                  $scope.greeting = 'Xin chào ' + $scope.username + '!';
                };
            }]);
        </script>
    </head>
    <body ng-app="scopeExample">
        <div ng-controller="MyController">
            Nhập tên của bạn:
            <input type="text" value="Framgia" ng-model="username"></input>
            <button ng-click='sayHello()'>In thông báo</button>
            <hr />
            {{ greeting }}
        </div>
    </body>
</html>

Xem demo ví dụ này.

  • Trong ví dụ trên mình có sử dụng một số directive đã được đề cập ở bài trước như ng-app, ng-model, còn directive ng-controller dưới đây mình sẽ nêu cụ thể. Ở đây mình muốn các bạn để ý đến directive ng-click trong thẻ button, khi bạn bấm vào button này function sayHello trong script sẽ được thực thi, gán giá trị cho các thuộc tính của $scope, cụ thể username là giá trị nhập vào từ ô input, còn greeting chính là câu thông báo cần hiển thị trên view.

II. AngularJS Controller

1. Khái niệm

  • Trong AngularJS, một controller được định nghĩa tương tự như hàm contructor của javascript, với đối số là object $scope, nó có nhiệm vụ khởi tạo, xây dựng các Model vào kết nối chúng với các View (HTML).

2. Nên sử dụng controller khi nào?

  • Khi cần thiết lập giá trị, trạng thái ban đầu cho object $scope.
  • Khi thêm các hàm, các hành vi vào đối tượng $scope.
  • Controller chỉ nên chứa các business logic.

3. Không sử dụng controller khi nào?

  • Thao tác với DOM (cái này sẽ được nhắc đến chi tiết hơn ở các bài sau) - hiểu nôm na là khi cần thay đổi giá trị nội dung, thuộc tính của các thẻ html thì không nên dùng controller mà ta dùng cơ chế data-binding của AngularJS.
  • Format input - hay nói cách khác là validate form kiểm tra định dạng dữ liệu của input của form, trường hợp này ta có thể dùng angular form controls thay thế
  • Filter output - lọc dữ liệu, chuyển đổi định dạng dữ liệu ta nên dùng angular filters.
  • Chia sẽ dữ liệu, trường hợp này dùng angular services.
  • Quản lý thời gian sống của các component.

4. Các ví dụ

  • Ví dụ 1: khởi tạo giá trị ban đầu cho object $scope
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf8">
        <title>AngularJS Controller</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script>
            var myApp = angular.module('myApp',[]);

            myApp.controller('GreetingController', ['$scope', function($scope) {
              $scope.greeting = 'Framgia!';
            }]);
        </script>
    </head>
    <body ng-app="myApp">
        <div ng-controller="GreetingController">
            <h1>Hello {{ greeting }}</h1>
        </div>
    </body>
</html>

Xem demo ví dụ này.

  • Ở phần body thì không có gì mới so với các ví dụ trước, ta dùng directive ng-app để khởi tạo app với tên myApp, directive ng-controller để khai báo controller GreetingController và kết quả trả lại được hiển thị ra theo cơ chế data-binding.

  • Trong đoạn script ở trên ta tạo ra một Angular Module (nơi chứa các định nghĩa các controllers, services, filters..) với đoạn mã var myApp = angular.module('myApp',[]);

  • Tiếp đến ta gọi đến phương thức .controller() khi đó một object global $scope được tạo ra, và ta khởi tạo cho thuộc tính greeting với giá trị là Framgia!. Kết quả thu được như các bạn đã thấy là dòng chữ Hello Framgia!.

  • Ví dụ 2: Controller method - thêm hành vi cho object $scope

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf8">
        <title>AngularJS Controller</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.controller('personCtrl', ['$scope', function($scope) {
                $scope.firstName = "Nguyen";
                $scope.lastName = "Phu";
                $scope.fullName = function() {
                    return $scope.firstName + " " + $scope.lastName;
                }
            }]);
        </script>
    </head>
    <body>
        <div ng-app="myApp" ng-controller="personCtrl">

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

        </div>
    </body>
</html>

Xem demo ví dụ này.

  • Khác với ở ví dụ 1, ví dụ này ngoài việc khởi tạo giá trị cho 2 thuộc tính firstName, lastName của đối tượng $scope, ta còn định nghĩa một method bên trong controller và gán cho thuộc tính fullName, method này sẽ sẽ sử lí việc trả lại fullName và trên view ta chỉ cần gọi {{ fullName() }}.

  • Nếu các bạn để ý thì có thể nhận ra ngay ví dụ này tương tự như ví dụ trong phần I. Scope ở trên.

  • Ví dụ 3:

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf8">
        <title>AngularJS Controller</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.controller('myController', ['$scope', function($scope) {
                $scope.position = "developer";

                $scope.position1 = function() {
                    $scope.position = "leader";
                }
                $scope.position2 = function() {
                    $scope.position = "manager";
                }
            }]);
        </script>
    </head>
    <body ng-app="myApp">
        <div ng-controller="myController">
            <button ng-click="position1()">position 1</button>
            <button ng-click="position2()">position 2</button>
            <p>Your position: {{ position }}</p>
        </div>
    </body>
</html>

Xem demo ví dụ này.

  • Ở ví dụ này object $scope có 1 thuộc tính position duy nhất nhưng có đến 2 method position1()positioin2(). Lần đầu tiên chạy ta sẽ thu được developer, nhưng khi ta click vào button tương ứng, thuộc tính position sẽ được ghi dè và cho ta kết quả tương ứng.

  • Tương tự ta cũng có thể định nghĩa nhiều controller trong 1 app như ví dụ tiếp theo.

  • Ví dụ 4:

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset="utf8">
        <title>AngularJS Controller</title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.controller('controller1', ['$scope', function($scope) {
                $scope.div = "DIV1";
            }]);
            app.controller('controller2', ['$scope', function($scope) {
                $scope.div = "DIV2";
            }]);
        </script>
    </head>
    <body ng-app="myApp">
        <div ng-controller="controller1">
            Welcome to {{ div }}!
        </div>
        <div ng-controller="controller2">
            Welcome to {{ div }}!
        </div>
    </body>
</html>

Xem demo ví dụ này.

  • Với ví dụ này ta thu được 2 kết quả của cùng một thuộc tính div, do phạm vi ảnh hưởng của object $scope còn phụ thuộc vào controller chứa nó.

III. Kết luận và tham khảo

  • Qua bài này chúng ta đã hiểu cơ bản về $scope, controller trong AngularJS, về định nghĩa cũng như cơ chế cách thức hoạt động của nó chính vì thế trong bài sau mình sẽ đưa controller vào các ví dụ nhiều hơn, để các bạn có thể nắm rõ và không bị quên kiến thức, giống như bài này mình nhắc đến và sử dụng khá nhiều directive trong bài lần trước.
  • Dưới đây là một số nguồn mình tham khảo trong khi viết bài:
  • Nếu các bạn có ý kiến đóng góp xin vui lòng để lại comment bên dưới, chúng ta sẽ cùng nhau mổ xẻ vấn đề. Xin cảm ơn!