$scope trong AngularJS là gì? Hướng dẫn kèm ví dụ.
⚡ Tóm tắt thông minh
`$Scope` trong AngularJS là đối tượng tích hợp sẵn dùng để liên kết bộ điều khiển với khung nhìn của nó. Trang này giải thích về việc tạo phạm vi, các hàm hành vi, hệ thống phân cấp cha con, sự khác biệt so với `$rootScope`, và cách các chu kỳ digest làm mới các liên kết.
$scope trong AngularJS là gì?
$ phạm vi trong AngularJS là một đối tượng tích hợp về cơ bản liên kết “bộ điều khiển” và “chế độ xem”. Người ta có thể xác định các biến thành viên trong phạm vi bên trong bộ điều khiển mà sau đó khung nhìn có thể được truy cập.
Mỗi bộ điều khiển trong một AngularJS Ứng dụng nhận được một thể hiện `$scope` riêng thông qua cơ chế tiêm phụ thuộc. Bất cứ thứ gì bạn gắn vào đối tượng đó đều trở nên hiển thị cho mẫu mà bộ điều khiển quản lý, vì vậy `$scope` hoạt động như một mô hình dữ liệu được chia sẻ nằm giữa ứng dụng của bạn và các ứng dụng khác. JavaLogic kịch bản và mã HTML của bạn.
Hãy xem xét ví dụ dưới đây:
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Giải thích:
- Tên của mô-đun là “ứng dụng”
- Tên của bộ điều khiển là “HelloWorldCtrl”
- Đối tượng phạm vi là đối tượng chính được sử dụng để truyền thông tin từ bộ điều khiển đến khung nhìn.
- Biến thành viên được thêm vào đối tượng phạm vi
⚠️ Cảnh báo cú pháp: .controller() Phương thức này nhận hai đối số, tên bộ điều khiển và hàm tạo, vì vậy cần có dấu phẩy giữa chúng. 'HelloWorldCtrl' và function($scope)Việc bỏ sót dấu phẩy sẽ gây ra lỗi. Uncaught SyntaxError Trước khi AngularJS được khởi tạo.
Một bộ điều khiển duy nhất và một giao diện duy nhất chỉ là một nửa bức tranh. Các ứng dụng thực tế lồng nhau các bộ điều khiển, lặp lại danh sách và tái sử dụng các widget, điều đó có nghĩa là có nhiều phạm vi tồn tại cùng một lúc.
Cách thức hoạt động của phân cấp phạm vi và kế thừa trong AngularJS
Mỗi ứng dụng AngularJS đều có chính xác một phạm vi gốc và có thể có bất kỳ số lượng phạm vi con nào. Các chỉ thị tạo ra các phạm vi con đó và gắn chúng vào phần tử DOM mà chúng trang trí, do đó cây phạm vi phản ánh cấu trúc của trang được hiển thị.
Khi AngularJS đánh giá một biểu thức như sau: {{siteName}}Đầu tiên, nó tìm kiếm thuộc tính đó trong phạm vi được gắn với phần tử. Nếu thuộc tính không có, quá trình tìm kiếm sẽ chuyển sang phạm vi cha và tiếp tục leo lên cho đến khi đạt đến phạm vi gốc. JavaCác nhà phát triển kịch bản biết hành vi này là kế thừa nguyên mẫu, và phạm vi con kế thừa từ phạm vi cha của chúng theo đúng cách đó.
Ví dụ bên dưới lồng một bộ điều khiển vào bên trong một bộ điều khiển khác để bạn có thể quan sát quá trình kế thừa.
<div ng-app="scopeDemo"> <div ng-controller="ParentCtrl"> Parent scope value: {{siteName}} <div ng-controller="ChildCtrl"> Child reads parent value: {{siteName}} Child own value: {{lesson}} </div> </div> </div> <script type="text/javascript"> var app = angular.module("scopeDemo", []); app.controller("ParentCtrl", function($scope) { $scope.siteName = "Guru99"; }); app.controller("ChildCtrl", function($scope) { $scope.lesson = "AngularJS Scope"; }); </script>
Code Giải thích:
ParentCtrlđịnh nghĩasiteNametrong phạm vi riêng của nó.ChildCtrlkhông bao giờ định nghĩasiteNameTuy nhiên, div bên trong vẫn in ra. Guru99 vì quá trình tra cứu truy cập đến phạm vi cha.lessonNó chỉ tồn tại trong phạm vi con, vì vậy div cha không thể đọc được nó.
Những chỉ thị nào tạo ra một phạm vi mới?
- ng-controller: Tạo một phạm vi con cho phần tử mà nó được đặt lên.
- ng-repeat: Mỗi lần lặp tạo ra một phạm vi con duy nhất, đó là lý do tại sao mỗi hàng có thể chứa các giá trị khác nhau cho cùng một biểu thức.
- Các chỉ thị tùy chỉnh: có thể yêu cầu kính nội soi cho trẻ em, hoặc một cô lập phạm vi này cố ý không kế thừa từ phạm vi cha của nó.
- Chỉ thị thành phần: bất cứ thứ gì được đăng ký với
.component()Người trợ giúp luôn nhận được một phạm vi cô lập.
Vì phạm vi con đọc từ dưới lên trên, các nhà phát triển thường tự hỏi đỉnh của chuỗi đó nằm ở đâu. Đối tượng cấp cao nhất đó được gọi là `$rootScope`.
$scope so với $rootScope: Sự khác biệt là gì?
AngularJS $rootScope $rootScope là phạm vi cho toàn bộ ứng dụng. Một ứng dụng chỉ có thể có một $rootScope duy nhất và nó được sử dụng như một biến toàn cục. Mỗi $scope là một phạm vi con, và $rootScope là phạm vi cha ở đỉnh của cây. Bảng dưới đây so sánh hai đối tượng này.
| Yếu tố | phạm vi $ | $rootScope |
|---|---|---|
| Số lượng phiên bản cho mỗi ứng dụng | Nhiều, mỗi bộ điều khiển hoặc chỉ thị tạo phạm vi có một chỉ thị. | Chính xác là một |
| Tạo bởi | Các chỉ thị như ng-controller và ng-repeat | Bộ tiêm trong quá trình khởi động ứng dụng |
| Hình ảnh tốt | Nguyên tố riêng của nó và tất cả các hậu duệ của nó | Mọi phạm vi trong ứng dụng |
| Sử dụng điển hình | Dữ liệu và hành vi cho một chế độ xem hoặc một hàng trong danh sách. | Các giá trị áp dụng trên toàn ứng dụng, chẳng hạn như người dùng đã đăng nhập. |
| rủi ro chính | Các giá trị trở nên không thể đạt được bên ngoài nhánh | Xung đột tên và liên kết ngầm, giống như các biến toàn cục. |
Hãy sử dụng `$rootScope` một cách tiết kiệm. Bất cứ thứ gì được đặt ở đó đều tồn tại trong toàn bộ ứng dụng và có thể đọc được ở mọi nơi, vì vậy một dịch vụ dùng chung thường là nơi an toàn hơn cho trạng thái toàn cục. (Lưu ý: Đoạn mã chính thức không liên quan đến đoạn mã trên.) Tham chiếu $rootScope Liệt kê toàn bộ API.
Biết được dữ liệu nằm ở đâu chỉ là một nửa công việc. Nửa còn lại là hướng dẫn nhóm phát triển cách phản hồi khi người dùng thực hiện thao tác nào đó.
Thiết lập hoặc thêm hành vi trong AngularJS
Để phản ứng với các sự kiện hoặc thực hiện một số loại tính toán/xử lý trong Chế độ xem, chúng tôi phải cung cấp hành vi cho phạm vi.
Các hành vi được thêm vào các đối tượng phạm vi để phản hồi các sự kiện cụ thể có thể được Chế độ xem kích hoạt. Khi hành vi được xác định trong bộ điều khiển, nó có thể được truy cập bằng chế độ xem.
Hãy xem một ví dụ về cách chúng ta có thể đạt được điều này.
<!DOCTYPE html> <html lang="en"> <head> <meta chrset="UTF 8"> <title>Guru99</title> </head> <body ng-app="DemoApp"> <h1> Guru99 Global Event</h1> <script src="https://code.angularjs.org/1.6.9/angular.js"></script> <div ng-controller="DemoController"> {{fullName("Guru","99")}} </div> <script type="text/javascript"> var app = angular.module("DemoApp", []); app.controller("DemoController", function($scope) { $scope.fullName=function(firstName,lastname){ return firstName + lastname; } } ); </script> </body> </html>
Code Giải thích:
- Chúng tôi đang tạo một hành vi có tên là “fullName”. Hành vi này là một hàm chấp nhận 2 tham số (firstName,lastname).
- Hành vi sau đó trả về kết nối của 2 tham số này.
- Trong quan điểm này, chúng ta đang gọi hành vi và truyền vào 2 giá trị của “Guru“ và “99” được truyền làm tham số cho hành vi.
Nếu lệnh được thực thi thành công, kết quả sau sẽ hiển thị khi bạn chạy mã trên trình duyệt.
Đầu ra:
Trong trình duyệt, bạn sẽ thấy sự kết hợp của cả hai giá trị. Guru & 99 được truyền sang hành vi trong điều khiển.
Các liên kết như trên tự động được làm mới, và việc hiểu rõ cơ chế hoạt động của chúng rất quan trọng trước khi ứng dụng phát triển lớn mạnh.
Tại sao Scope Watchers và chu kỳ tóm tắt lại quan trọng?
AngularJS duy trì sự đồng bộ giữa giao diện người dùng và phạm vi bằng cách kiểm tra thay đổi (dirty checking) thay vì thông qua các sự kiện thay đổi (change events). Ba API phạm vi điều khiển quá trình này:
- $watch: Đăng ký trình lắng nghe cho một biểu thức. Các phép nội suy như
{{fullName}}Đăng ký người theo dõi cho bạn trong quá trình liên kết mẫu. - $apply: Nó đi vào ngữ cảnh thực thi của AngularJS, đánh giá mã của bạn và sau đó kích hoạt một hàm xử lý. Nó chỉ cần thiết bên trong các hàm gọi lại sự kiện tùy chỉnh hoặc hàm gọi lại thư viện bên thứ ba, vì các chỉ thị tích hợp sẵn đã gọi nó rồi.
- $digest: Duyệt qua từng watcher trên $rootScope và các watcher con của nó, so sánh giá trị hiện tại với giá trị trước đó, và lặp lại cho đến khi mô hình ngừng thay đổi.
Vì quá trình xử lý digest có thể chạy nhiều lần, nên các biểu thức theo dõi (watch expressions) phải có chi phí thấp. Tránh truy cập DOM bên trong chúng, vì việc đọc DOM chậm hơn nhiều lần so với việc đọc một đối tượng khác. JavaThuộc tính kịch bản.
Độ sâu của đồng hồ cũng ảnh hưởng đến chi phí. Đồng hồ theo giá trị tham chiếu là phương pháp nhanh nhất và chỉ phát hiện khi toàn bộ giá trị được thay thế. $watchCollection Thông báo các mục được thêm, xóa hoặc sắp xếp lại bên trong một mảng hoặc đối tượng. Việc theo dõi theo giá trị sẽ duyệt qua một cấu trúc lồng nhau trên mỗi bản tóm tắt và là tùy chọn tốn kém nhất, vì vậy hãy sử dụng nó sau cùng.




