Tôi khuyên bạn nên đọc tài liệu Angular chuyên sâu chính thức về phạm vi. Bắt đầu ở phần 'Phạm vi phân cấp':
https://docs.angularjs.org/guide/scope
Về cơ bản, $ rootScope và $ scope đều xác định các phần cụ thể của DOM trong đó
- Các hoạt động góc được thực hiện
- các biến được khai báo như một phần của phạm vi $ rootScope hoặc $ đều có sẵn
Bất kỳ thứ gì thuộc về $ rootScope đều có sẵn trên toàn cầu trên ứng dụng Angular của bạn, trong khi bất kỳ thứ gì thuộc về phạm vi $ đều có sẵn trong phần DOM mà phạm vi đó áp dụng.
$ RootScope được áp dụng cho phần tử DOM là phần tử gốc của ứng dụng Angular (do đó có tên là $ rootScope). Khi bạn thêm chỉ thị ng-app vào một phần tử của DOM, phần tử này sẽ trở thành phần tử gốc của DOM trong đó $ rootScope có sẵn. Nói cách khác, các thuộc tính, v.v. của $ rootScope sẽ có sẵn trong toàn bộ ứng dụng Angular của bạn.
Phạm vi Angular $ (và tất cả các biến và hoạt động của nó) có sẵn cho một tập hợp con cụ thể của DOM trong ứng dụng của bạn. Cụ thể, $ scope cho bất kỳ bộ điều khiển cụ thể nào có sẵn cho phần DOM mà bộ điều khiển cụ thể đó đã được áp dụng (sử dụng lệnh ng-controller). Mặc dù vậy, lưu ý rằng một số lệnh nhất định, ví dụ ng-repeat, khi được áp dụng trong một phần của DOM nơi bộ điều khiển đã được áp dụng, có thể tạo các phạm vi con của phạm vi chính - trong cùng một bộ điều khiển - một bộ điều khiển không nhất thiết chỉ chứa một phạm vi.
Nếu bạn nhìn vào HTML được tạo khi chạy ứng dụng Angular, bạn có thể dễ dàng thấy phần tử DOM nào 'chứa' phạm vi, vì Angular thêm lớp ng-scope trên bất kỳ phần tử nào mà phạm vi đã được áp dụng (bao gồm cả phần tử gốc của ứng dụng, có $ rootScope).
Nhân tiện, dấu '$' ở đầu $ scope và $ rootScope chỉ đơn giản là một mã định danh trong Angular cho những thứ được Angular dành riêng.
Lưu ý rằng việc sử dụng $ rootScope để chia sẻ các biến, v.v. giữa các mô-đun và bộ điều khiển thường không được coi là phương pháp hay nhất. Các nhà phát triển JavaScript nói về việc tránh 'ô nhiễm' phạm vi toàn cầu bằng cách chia sẻ các biến ở đó, vì có thể xảy ra xung đột sau này nếu một biến cùng tên được sử dụng ở một nơi khác mà nhà phát triển không nhận ra rằng nó đã được khai báo trên $ rootScope. Tầm quan trọng của điều này tăng lên theo quy mô của ứng dụng và nhóm phát triển nó. Lý tưởng nhất là $ rootScope sẽ chỉ chứa các hằng số hoặc các biến tĩnh, nhằm mục đích nhất quán mọi lúc trên ứng dụng. Một cách tốt hơn để chia sẻ nội dung giữa các mô-đun có thể là sử dụng các dịch vụ và nhà máy, đây là một chủ đề khác!