"Làm thế nào this
và $scope
hoạt động trong bộ điều khiển AngularJS?"
Câu trả lời ngắn gọn :
this
- Khi hàm xây dựng bộ điều khiển được gọi,
this
là bộ điều khiển.
- Khi một hàm được định nghĩa trên một
$scope
đối tượng được gọi, this
là "phạm vi có hiệu lực khi hàm được gọi". Điều này có thể (hoặc có thể không!) $scope
Là chức năng được xác định trên. Vì vậy, bên trong chức năng, this
và $scope
có thể không giống nhau.
$scope
- Mỗi bộ điều khiển có một
$scope
đối tượng liên quan .
- Hàm điều khiển (hàm tạo) chịu trách nhiệm thiết lập các thuộc tính mô hình và các hàm / hành vi trên mô hình được liên kết
$scope
.
- Chỉ các phương thức được xác định trên
$scope
đối tượng này (và các đối tượng phạm vi cha, nếu kế thừa nguyên mẫu đang hoạt động) có thể truy cập được từ HTML / view. Ví dụ: từ ng-click
, bộ lọc, v.v.
Câu trả lời dài :
Hàm điều khiển là hàm xây dựng JavaScript. Khi hàm xây dựng thực thi (ví dụ: khi chế độ xem tải), this
(nghĩa là "bối cảnh chức năng") được đặt thành đối tượng điều khiển. Vì vậy, trong hàm tạo của trình điều khiển "tab", khi hàm addPane được tạo
this.addPane = function(pane) { ... }
nó được tạo trên đối tượng điều khiển, không phải trên phạm vi $. Các khung nhìn không thể thấy hàm addPane - chúng chỉ có quyền truy cập vào các hàm được xác định trên $ scope. Nói cách khác, trong HTML, điều này sẽ không hoạt động:
<a ng-click="addPane(newPane)">won't work</a>
Sau khi hàm xây dựng bộ điều khiển "tab" thực thi, chúng ta có các bước sau:
Đường màu đen nét đứt biểu thị sự kế thừa nguyên mẫu - một phạm vi cô lập kế thừa nguyên mẫu từ Phạm vi . (Nó không được kế thừa nguyên mẫu từ phạm vi có hiệu lực trong đó lệnh được gặp trong HTML.)
Bây giờ, chức năng liên kết của chỉ thị khung muốn giao tiếp với chỉ thị tab (điều này thực sự có nghĩa là nó cần ảnh hưởng đến các tab cách ly $ scope theo một cách nào đó). Các sự kiện có thể được sử dụng, nhưng một cơ chế khác là có khung chỉ thị require
điều khiển tab. (Dường như không có cơ chế nào cho chỉ thị khung cho require
các tab $ scope.)
Vì vậy, điều này đặt ra câu hỏi: nếu chúng ta chỉ có quyền truy cập vào trình điều khiển tab, làm thế nào để chúng ta có quyền truy cập vào các tab cô lập $ scope (đó là điều chúng ta thực sự muốn)?
Vâng, đường chấm màu đỏ là câu trả lời. "Phạm vi" của hàm addPane () (Tôi đang đề cập đến phạm vi / đóng của hàm JavaScript ở đây) cung cấp cho hàm truy cập vào các tab cách ly $ scope. Tức là addPane () có quyền truy cập vào "tab IsolateScope" trong sơ đồ ở trên vì một bao đóng được tạo khi addPane () được xác định. (Nếu chúng ta thay vào đó đã xác định addPane () trên đối tượng tab scope scope, lệnh directive sẽ không có quyền truy cập vào hàm này và do đó nó sẽ không có cách nào để giao tiếp với các tab $ scope.)
Để trả lời phần khác của câu hỏi của bạn how does $scope work in controllers?
::
Trong các hàm được định nghĩa trên $ scope, this
được đặt thành "phạm vi $ có hiệu lực trong đó / khi hàm được gọi". Giả sử chúng ta có HTML sau:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
Và ParentCtrl
(Hoàn toàn) có
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Nhấp vào liên kết đầu tiên sẽ hiển thị this
và $scope
giống nhau, vì " phạm vi có hiệu lực khi hàm được gọi " là phạm vi được liên kết với ParentCtrl
.
Nhấn vào liên kết thứ hai sẽ tiết lộ this
và $scope
là không giống nhau, vì " phạm vi hiệu lực khi hàm được gọi " là phạm vi liên quan đến việc ChildCtrl
. Vì vậy, ở đây, this
được thiết lập để ChildCtrl
's $scope
. Bên trong phương thức, $scope
vẫn ParentCtrl
là phạm vi $ s.
Vĩ cầm
Tôi cố gắng không sử dụng this
bên trong hàm được xác định trên $ scope, vì nó trở nên khó hiểu khi phạm vi $ đang bị ảnh hưởng, đặc biệt là xem xét rằng ng-repeat, ng-include, ng-switch và chỉ thị đều có thể tạo phạm vi con của riêng chúng.