ANGULARJS
Cách giao tiếp giữa $rootScope, $broadcast và $emit trong AngularJS Tạo ứng dụng SPA trong AngularJS với Routing và StateProvider. Sử dụng Karma và Jasmine để test ứng dụng AngularJS Ứng dụng di động đa nền tảng với Ionic và React Native trong AngularJS Tích hợp thư viện và module bằng Bower và npm vào Angular Xử lý lỗi với $exceptionHandler và $log service trong AngularJS. Sử dụng Custom Directives trong AngularJS Interceptors và Http Service trong Angular Tạo và sử dụng directive trong AngularJS Cách sử dụng service trong AngularJS Cách sử dụng Dependency Injection trong AngularJS Cách sử dụng route trong AngularJS Tạo hiệu ứng với ngAnimate trong AngularJS Tối ưu hóa hiệu suất trong AngularJS Security trong AngularJS và cách sử dụng đơn giản Đa ngôn ngữ Internationalization (i18n) trong AngularJS Two way data binding trong Angularjs Bài 01: Tổng quan về AngularJS Bài 02: Download AngularJS và viết ứng dụng AngularJS đầu tiên Bài 03: Tìm hiểu Controller trong AngularJS Bài 04: Tìm hiểu Scope và rootScope trong AngularJS Bài 05: Tìm hiểu AngularJS Directives - Danh sách Directives Bài 06: Directive ng-model trong AngularJS Bài 07: Directive ng-model-options trong AngularJS Bài 08: Directives ng-bind - ng-bind-html - ng-bind-template trong AngularJS Bài 09: Directive Form trong AngularJS Bài 10: Directive ng-form trong AngularJS Bài 11: Directive input trong AngularJS Bài 12: Directive input checkbox trong AngularJS Bài 13: Directive input date trong AngularJS Bài 14: Directive input datetime-local trong AngularJS Bài 15: Directive input time trong AngularJS Bài 16: Directive input month và input week trong AngularJS Bài 17: Directive ng-show và ng-hide trong AngularJS Bài 18: Directive ng-repeat trong AngularJS Bài 19: Directive ng-init trong AngularJS Bài 20: Directive ng-include trong AngularJS Bài 21: Services trong AngularJS và cách tạo Service mới Bài 22: Directive ng-class trong angularjs Tạo tabs với ng-show & ng-class & ng-click trong angularjs Bài 23: Directive ng-click trong angularjs Bài 24: Directive ng-class-odd và ng-class-even trong Angularjs [Học AngularJS] - Bài 01 - Hello World! [Học AngularJS] - Bài 02 - ng-app [Học AngularJS] - Bài 03 - ng-controller [Học AngularJS] - Bài 04 - $scope [Học AngularJS] - Bài 05 - $rootScope
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Bài 04: Tìm hiểu Scope và rootScope trong AngularJS

Các ví dụ ở bài trước chúng ta đã sử dụng đối tượng $scope rất nhiều rồi và tôi cũng đa có giải thích tác dụng và cách dùng của nó, nhưng để các bạn dễ hình dung hơn thì trong bài này chúng ta sẽ tìm hiểu kỹ hơn đối tượng $scope này. Nhưng trước khi bắt đầu bạn nên ôn kỹ các bài trước đã nhé.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

1. Scope là gì?

$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. Nó sẽ thực hiện dưới dạng biểu thức, nghĩa là ở model sẽ được khai báo đúng với quy cách thì đối tượng scope sẽ truyền hành động (function) hoặc dữ liệu tương ứng và ta có thể truyền các sự kiện thông qua đối tượng này.

Scopes cung cấp các biểu thức giống như các template engine hiện nay, ví dụ để hiển thị username thì ta sẽ khai báo là {{username}} và ở controller chúng ta chỉ việc gán $scope.username = 'something' thì đối tượng này sẽ lấy key có tên là username gán vào view {{username}}.

$scope là cầu nối giữa controller và view

Điều này mình thấy cũng đúng thật, nghĩa là bạn thêm dữ liệu cho $scope ở controller thì nếu bên view có khai báo theo đúng quy tắc thì nó sẽ tự đống gán thông tin vào đúng vị trí đó. 

Bài viết này được đăng tại [free tuts .net]

Ví dụ: XEM DEMO

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
    </head>
    <body ng-app="myapp">
        <div ng-controller="MyController">
            Nhập tên của bạn:
            <input type="text" value="" ng-model="username">
            <button ng-click='sayHello()'>In thông báo</button>
            <hr>
            {{greeting}}
        </div>
        <script>
            angular.module('myapp', [])
            .controller('MyController', ['$scope', function($scope) 
            {
                $scope.sayHello = function() {
                  $scope.greeting = 'Xin chào ' + $scope.username + '!';
                };
            }]);
        </script>
    </body>
</html>
Trong ví dụ này tôi khai báo một action ng-click ="sayHello()" có ý nghĩa rằng khi click vào input đó thì nó sẽ gọi đến hàm sayHello() mà ta định nghĩa trong $scope ở controller.

$scope.sayHello = function() {
  $scope.greeting = 'Xin chào ' + $scope.username + '!';
};

Trong hàm sayHello() có nhiệm vụ là đổi giá trị cho gretting, điều này có nghĩa là nó đang gán lại giá trị cho view ở biểu thức {{greeting}}

Ngoài ra tôi còn khai báo thêm input có thuộc tính ng-model="username" 

<input type="text" value="" ng-model="username">

Điều này có nghĩa rằng ta đang khai báo đây là một model với key của nó là username, muốn lấy dữ liệu của nó chỉ cần sử dụng $scope như sau "$scope.username", và muốn gán thì ta sẽ dùng cú pháp $scope.username = 'giá trị'

2. Phạm vi ảnh hưởng của $scope

Trong một ứng dụng AngularJS thì ta có thể có nhiều Controller, nhiều $scope khác nhau. Các bạn xem ví dụ dưới đây:

XEM DEMO

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
        <style>
            .show-scope-demo.ng-scope,
            .show-scope-demo .ng-scope  {
                border: 1px solid red;
                margin: 3px;
            }
            .show-scope-demo .ng-scope .ng-scope{
                border:solid 1px blue;
            }
        </style>
    </head>
    <body ng-app="myapp">
        <div class="show-scope-demo">
            <div ng-controller="GreetController">
                Hello {{name}}!
            </div>
            <div ng-controller="ListController">
                Hello {{name}}!
            </div>
        </div>
        <script>
            angular.module("myapp", [])
                    .controller('GreetController', function ($scope){
                        $scope.name = 'Nguyễn Văn Cường';
                    })
                    .controller('ListController', function ($scope){
                        $scope.name = 'Học Lập Trình Online';
                    });
        </script>
    </body>
</html>

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';
});

Như vậy rõ ràng trong 2 view có hai giá trị {{name}} thì làm sao $scope nhận biết mà truyền dữ liệu được? Đó chính là do ta khai báo ng-controller ở div bên ngoài nên trong đoạn js nó hiểu là giá trị {{name}} nằm trong controller hiện tại. Chạy lên giao diện như sau:

phạm vi hoạt động của scope

3. Tìm Hiểu $rootScope 

Tiếp tục ví dụ ở phần 2, bây giờ ta sẽ đổi một chút cú pháp của đoạn mã AngularJS như sau:

XEM DEMO

<script>
    angular.module("myapp", [])
            .controller('GreetController', function ($scope, $rootScope){
                $rootScope.name = 'Học Lập';
            })
            .controller('ListController', function ($scope){

            });
</script>
Trong đoạn ví dụ này sự khác biệt chính là ở đoạn mã JS Controller thứ nhất có thêm tham số $rootScope, và ở đoạn Controller thứ hai thì không xử lý gì cả. Chạy lên các bạn thấy giao diện như sau:

scope root

Như vậy rõ ràng đoạn code trên mình không truyền giá trị cho $scope ở cả 2 controller mà bên view vẫn có? Đó là vì biến $rootScope. Điều này có nghĩa là khi ứng dụng được chạy thì sẽ có một $rootScope được tự động tạo, $rootScope là bậc cao nhất nên sẽ bao quát hết các $scope bên trong nó, điêu này không giống với $scope là chỉ ảnh hưởng trong phạm vi của controller.

4. $scope lồng nhau

Bây giờ ta sẽ thêm một controller ngoài cùng bao cả hai controller như ở ví dụ trên, mã HTML lại như sau:

XEM DEMO

<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>
Và đoạn JS sửa lại chút:

angular.module("myapp", [])
        .controller('TopController', function ($scope){
            $scope.name = 'demo';
        })
        .controller('GreetController', function ($scope){

        })
        .controller('ListController', function ($scope){

        });
Chạy lên giao diện như sau:

Scope lồng nhau

Các bạn thấy trong 2 controller bên trong mình không code gì cả mà tại sao view vẫn nhận được giá trị? Đó chính là do controller ngoài cùng mình khai báo $scope.name = 'demo' nên nó sẽ nhận cả bên trong. 

Bây giờ bạn sửa đoạn code JS lại một xíu: 

XEM DEMO

angular.module("myapp", [])
        .controller('TopController', function ($scope){
            $scope.name = 'demo';
        })
        .controller('GreetController', function ($scope){
            $scope.name = 'freetuts';
        })
        .controller('ListController', function ($scope){
            $scope.name = 'Coder';
        });
Chạy lên giao diện sẽ như sau:

scope long nhau 2 png

Thú vị phải không nào, theo nguyên tắc chạy thì controller thứ nhất ngoài cùng sẽ chạy trước và tất cả các {{name}} đều có giá trị là demo, nhưng các controller còn lại nó tự gán lại giá trị cho các {{name}}  của nó nên giá trị demo sẽ bị ghi đè thành giá trị mới.

Khi nói tới $rootScope$scope lồng nhau thì rất nhiều ví dụ nhưng mình chỉ đưa ra được bấy nhiêu đây thôi, còn lại các bạn tự test để rút ra bài học nhé vì mình không thể trình bày full ở đây được, mong các bạn thông cảm.

5. Bật Firebug để xem các class tự tạo trong angularjs

Tới đây không biết bạn có thắc mắc tại sao các kết quả trên có đường viền màu đỏ và màu xanh không? Đấy là do mình khai báo trong đoạn CSS:

.show-scope-demo .ng-scope  {
    border: 1px solid red;
    margin: 3px;
}
.show-scope-demo .ng-scope .ng-scope{
    border:solid 1px blue;
}
Đoạn CSS này báo rằng class .ng-scope thứ nhất sẽ là border màu đỏ, class .ng-scope thứ hai sẽ là border màu xanh. Nhưng đoạn mã HTML mình không có tạo class này mà tạo sao kết quả vẫn có? Đó là tại vì AngularJS tự động thêm vào đấy các bạn. Ứng dụng có bao nhiêu $scope (controller) thì nó sẽ tạo bấy nhiêu cái, nếu lồng nhau thì class đó sẽ tạo lồng nhau. Không tin các bạn xem hình dưới đây nhé:

scope long nhau 3 png

Ô màu đỏ tượng trưng cho border màu đỏ, ô màu xanh tượng trưng cho border màu xanh.

6. Lời kết

Nói về $scope thật sự còn rất nhiều nhưng vì phạm vi bài quá dài nên mình sẽ tạm dừng ở đây, nếu chúng ta tiếp tục tìm hiểu $scope nâng cao thì bản thân mình thấy chưa cần thiết, vì chúng ta phải thực hành nhiều và nhiều hơn nữa, nếu đi quá nhiều thì bạn sẽ không nhớ bao nhiêu. Nên vấn đề này chúng ta sẽ tìm hiểu ở một bài nào đó tiếp theo trong serie này nhé. 

Cùng chuyên mục:

Tích hợp thư viện và module bằng Bower và npm vào Angular

Tích hợp thư viện và module bằng Bower và npm vào Angular

Ứng dụng di động đa nền tảng với Ionic và React Native trong AngularJS

Ứng dụng di động đa nền tảng với Ionic và React Native trong AngularJS

Sử dụng Karma và Jasmine để test ứng dụng AngularJS

Sử dụng Karma và Jasmine để test ứng dụng AngularJS

Tạo ứng dụng SPA trong AngularJS với Routing và StateProvider.

Tạo ứng dụng SPA trong AngularJS với Routing và StateProvider.

Cách giao tiếp giữa $rootScope, $broadcast và $emit trong AngularJS

Cách giao tiếp giữa $rootScope, $broadcast và $emit trong AngularJS

Two way data binding trong Angularjs

Two way data binding trong Angularjs

Đa ngôn ngữ Internationalization (i18n) trong AngularJS

Đa ngôn ngữ Internationalization (i18n) trong AngularJS

Security trong AngularJS và cách sử dụng đơn giản

Security trong AngularJS và cách sử dụng đơn giản

Tối ưu hóa hiệu suất trong AngularJS

Tối ưu hóa hiệu suất trong AngularJS

Xử lý lỗi với $exceptionHandler và $log service trong AngularJS.

Xử lý lỗi với $exceptionHandler và $log service trong AngularJS.

Tạo hiệu ứng với ngAnimate trong AngularJS

Tạo hiệu ứng với ngAnimate trong AngularJS

Cách sử dụng route trong AngularJS

Cách sử dụng route trong AngularJS

Cách sử dụng Dependency Injection trong AngularJS

Cách sử dụng Dependency Injection trong AngularJS

Cách sử dụng service trong AngularJS

Cách sử dụng service trong AngularJS

Tạo và sử dụng directive trong AngularJS

Tạo và sử dụng directive trong AngularJS

Interceptors và Http Service trong Angular

Interceptors và Http Service trong Angular

Sử dụng Custom Directives trong AngularJS

Sử dụng Custom Directives trong AngularJS

Thiết lập project với Angular 6

Thiết lập project với Angular 6

Ở bài trước, chúng ta đã tìm hiểu cách cài đặt môi trường cũng như…

Cài đặt môi trường cho Angular 6

Cài đặt môi trường cho Angular 6

Ở bài trước, chúng ta đã tìm hiểu vì sao chọn Angular, Angular 6 là…

Giới thiệu Angular 6x

Giới thiệu Angular 6x

Xin giới thiệu với các bạn tổng quan tất cả các bài viết học về…

Top