Scope và rootScope trong AngularJS – Web888 chia sẻ kiến thức lập trình, kinh doanh, mmo

Ở những bài trước, tất cả chúng ta đã tạm hiểu cấu trúc MVC của AngularJS :

  • View: dữ liệu hiển thị HTML
  • Model: dữ liệu làm việc với view hiện tại
  • Controller: luồng logic được viết bằng angularJS functions, sử dụng để thêm, sửa, xóa dữ liệu

$ scope là một object ( đối tượng người dùng ) có trách nhiệm tiếp xúc tài liệu giữa controller và view của ứng dụng, tất cả chúng ta hoàn toàn có thể hiểu là cầu nối, khi biến $ scope biến hóa, tài liệu ở controller và view cùng được update đồng điệu. Nó sẽ thực thi dưới dạng biểu thức, nghĩa là ở Mã Sản Phẩm sẽ được khai báo đúng với quy cách thì đối tượng người dùng scope sẽ truyền hành vi ( function ) hoặc tài liệu tương ứng và ta hoàn toàn có thể truyền những sự kiện trải qua đối tượng người tiêu dùng này .
Scopes phân phối những biểu thức giống như những template engine lúc bấy giờ, ví dụ để hiển thị username thì ta sẽ khai báo là { { username } } và ở controller tất cả chúng ta chỉ việc gán $ scope.username = ‘ toanngo92 ’ thì đối tượng người dùng này sẽ lấy key có tên là username gán vào view { { username } } .

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. Quay trở lại ví dụ dưới đây:






    
    
    
    Example Controller
    


    
{{name}} - {{data}}
{{name}} - {{data}}
{{name}} - {{data}}

Chúng ta thấy trong những view link tới controller tương ứng đều giá trị { { data } } khác nhau tuy nhiên mỗi một controller, thuộc tính data trong biến ở mỗi controller khác nhau. Điều này chứng tỏ cho việc khoanh vùng phạm vi của biến $ scope chỉ nằm trong controller tương ứng .

$rootScope và cấu trúc phân tầng của $scope

Ví dụ số 1:






    
    
    
    Document
    
	


    
Data rootscope: {{name}}
Data scope { { name } }

Kết quả khi in ra, và tương tác với input

Với ví dụ trên, chúng ta thấy mình có sử dụng một div và gọi model name ra view, tuy nhiên model này không thuộc controller nào, chúng ta hiểu ở dưới tầng script, thông qua phương thức app.run(), chúng ta đã khởi tạo một model toàn cục tên là name, nên mặc dù không nằm trong controller nào, chúng ta vẫn có thể biểu diễn ra biến name. còn đối với model name ở cấu trúc div bên trong indexController, chúng ta thấy khi cập nhật dữ liệu, model ở controller thay đổi nhưng không liên quan gì tới model bên ngooài, điều đó có ý nghĩa, 2 model name nằm trong $scope$rootScope mặc dù cùng tên nhưng bản chất chúng không liên quan tới nhau

Ví dụ số 2:

bây giờ ta sẽ đổi một chút cú pháp của đoạn mã AngularJS như sau:

Trong đoạn ví dụ này sự độc lạ 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 giải quyết và xử lý gì cả. Chạy lên những bạn thấy giao diện như sau :
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 hóa tạo, $ rootScope là bậc cao nhất nên sẽ bao quát hết những $ scope bên trong nó, điêu này không giống với $ scope là chỉ ảnh hưởng tác động trong khoanh vùng phạm vi của controller .
Xét ví dụ phía dưới :






    
    
    
    Example Controller
    


    
{{name}} - {{data}} {{data_global}}
{{name}} - {{data}}
{{name}} - {{data}}

Kết quả in ra màn hình hiển thị :

Bổ sung thêm một số ít thông tin ở ví dụ phía trên, có 2 ý cần chăm sóc :

  • Ở headerController, 2 thuộc tính $scope.data và $rootScope.data được đặt tên giống nhau (data), tuy nhiên khi in ra view bằng biểu thức, giá trị sẽ được lấy từ thuộc tính data của bến $scope, chứng minh nếu trong trường hợp model có tên giống nhau, $scope sẽ đưược ưu tiên so với $rootScope
  • Ở footerController, có một thuộc tính có tên data_global do mình tự đặt, tuy nhiên ở tầng view liên kết với headerController, mình lại cố tình gọi model data_global này ra, nhưng views vẫn nhận diện được, điều này chứng minh dữ liệu trong $rootScope có tính toàn cục ( có thể sử dụng để dùng chung hoặc truyền dữ liệu giữa các controller)

Nested Scope (scope lồng nhau)

Trong angularJS, chúng ta có thêm khái niệm các controller lồng nhau, tương tự các scope cũng lồng nhau, với tình huống này cần rất cẩn thận vì sẽ có nhiều tình huống không phân biệt được đang sử dụng scope nào. Xét ví dụ phía dưới:







    
    
    
    Document
    



    What controller am I? {{parentVariable}}
    
What controller am I? {{childVariable}} {{parentVariable}}

Kết quả khi chạy thử và bấm nút override :

Vấn đề ở đây, khi log biến $ scope ra, tài liệu parentVariable đã đổi khác, tuy nhiên parentVariable ở parentController lại không được update, yếu tố này sẽ thực sự gây khó hiểu và phiền phức trong quy trình coding, nên lời khuyên cho bạn là nên đặt tên biến rõ ràng, nếu có phải sử dụng nested controller thì nên tìm hiểu và khám phá cấu trúc thật kỹ để tránh phát sinh lỗi không mong ước .
Ngoài ra, nếu nói về scope thì thực sự sẽ có rất nhiều yếu tố, tuy nhiên trong khuôn khổ tiếp cận, những khái niệm này là những thứ tất cả chúng ta cần chớp lấy trước khi đi vào làm một ứng dụng trong thực tiễn với angularjs .