"ทำงานอย่างไรthis
และ$scope
ทำงานในคอนโทรลเลอร์ของ AngularJS ได้อย่างไร"
คำตอบสั้น ๆ :
this
- เมื่อเรียกใช้ฟังก์ชั่นคอนสตรัคเตอร์คอนโทรลเลอร์จะ
this
เป็นคอนโทรลเลอร์
- เมื่อฟังก์ชั่นที่กำหนดไว้ใน
$scope
วัตถุถูกเรียกthis
เป็น "ขอบเขตที่มีผลบังคับใช้เมื่อมีการเรียกใช้ฟังก์ชัน" สิ่งนี้อาจ (หรืออาจไม่ใช่!) เป็น$scope
ฟังก์ชันที่กำหนดไว้ ดังนั้นภายในฟังก์ชั่นthis
และ$scope
อาจไม่เหมือนกัน
$scope
- ทุกตัวควบคุมมี
$scope
วัตถุที่เกี่ยวข้อง
- ตัวควบคุม (คอนสตรัค) ฟังก์ชั่นเป็นผู้รับผิดชอบสำหรับการตั้งค่าคุณสมบัติรูปแบบและฟังก์ชั่น /
$scope
พฤติกรรมที่เกี่ยวข้อง
- เฉพาะวิธีการที่กำหนดไว้ใน
$scope
วัตถุนี้(และวัตถุขอบเขตของแม่ถ้ามรดกต้นแบบอยู่ในการเล่น) สามารถเข้าถึงได้จาก HTML / มุมมอง เช่นจากng-click
ตัวกรอง ฯลฯ
คำตอบยาว :
ฟังก์ชั่นควบคุมเป็นฟังก์ชั่นตัวสร้างจาวาสคริปต์ เมื่อฟังก์ชันตัวสร้างดำเนินการ (เช่นเมื่อโหลดมุมมอง), this
(กล่าวคือ "บริบทฟังก์ชัน") ถูกตั้งค่าเป็นวัตถุตัวควบคุม ดังนั้นในฟังก์ชั่นตัวควบคุม "แท็บ" เมื่อสร้างฟังก์ชั่น addPane
this.addPane = function(pane) { ... }
มันถูกสร้างขึ้นบนวัตถุตัวควบคุมไม่ใช่ในขอบเขต $ มุมมองไม่สามารถเห็นฟังก์ชั่น addPane - พวกเขามีการเข้าถึงฟังก์ชั่นที่กำหนดไว้ใน $ scope เท่านั้น กล่าวอีกนัยหนึ่งใน HTML สิ่งนี้จะไม่ทำงาน:
<a ng-click="addPane(newPane)">won't work</a>
หลังจากฟังก์ชั่นตัวควบคุม "แท็บ" ของตัวควบคุมดำเนินการเรามีดังต่อไปนี้:
เส้นสีดำประบ่งชี้มรดก prototypal - ขอบเขตแยก prototypically สืบทอดจากขอบเขต (ไม่ได้สืบทอดมาจากขอบเขตที่มีผลบังคับใช้เมื่อพบคำสั่งใน HTML)
ตอนนี้ฟังก์ชั่นการเชื่อมโยงของคำสั่งบานหน้าต่างต้องการสื่อสารกับคำสั่งของแท็บ (ซึ่งหมายความว่าจำเป็นต้องส่งผลกระทบต่อแท็บแยกขอบเขต $ ในบางวิธี) สามารถใช้เหตุการณ์ได้ แต่กลไกอีกอย่างหนึ่งคือการให้บานหน้าต่างrequire
ควบคุมตัวควบคุมแท็บ (ดูเหมือนจะไม่มีกลไกสำหรับคำสั่งบานหน้าต่างเพื่อrequire
ขอบเขต $ แท็บ)
ดังนั้นสิ่งนี้จึงเป็นคำถาม: หากเรามีสิทธิ์เข้าถึงตัวควบคุมแท็บเราจะเข้าถึงแท็บแยกขอบเขต $ ได้อย่างไร (ซึ่งเป็นสิ่งที่เราต้องการจริงๆ)?
เส้นประสีแดงคือคำตอบ addPane () "ขอบเขต" ของฟังก์ชัน (ฉันอ้างถึงขอบเขต / ปิดฟังก์ชันของ JavaScript ที่นี่) ให้การเข้าถึงฟังก์ชันกับแท็บแยก $ scope นั่นคือ addPane () มีการเข้าถึง "tabs IsolateScope" ในแผนภาพด้านบนเนื่องจากการปิดที่สร้างขึ้นเมื่อกำหนด addPane () (ถ้าเราแทนที่จะกำหนด addPane () บนวัตถุ $ scope แท็บคำสั่งบานหน้าต่างจะไม่สามารถเข้าถึงฟังก์ชั่นนี้และด้วยเหตุนี้มันจะไม่มีวิธีสื่อสารกับแท็บ $ scope)
ในการตอบคำถามอื่น ๆ ของคุณhow does $scope work in controllers?
:
ภายในฟังก์ชั่นที่กำหนดไว้ใน $ scope this
ถูกตั้งค่าเป็น "ขอบเขต $ มีผลบังคับใช้ที่ / เมื่อฟังก์ชันถูกเรียกว่า" สมมติว่าเรามี HTML ดังต่อไปนี้:
<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>
และสิ่งที่ParentCtrl
(เท่านั้น) มี
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
คลิกที่ลิงค์แรกจะแสดงให้เห็นว่าthis
และ$scope
จะเหมือนกันตั้งแต่ " ขอบเขตในผลเมื่อฟังก์ชั่นที่ถูกเรียกว่า " ParentCtrl
ขอบเขตที่เกี่ยวข้องกับ
คลิกที่ลิงค์ที่สองจะเปิดเผยthis
และ$scope
มีไม่เหมือนกันตั้งแต่ " ขอบเขตในผลเมื่อฟังก์ชั่นที่ถูกเรียกว่า " ChildCtrl
ขอบเขตที่เกี่ยวข้องกับ ดังนั้นที่นี่this
มีการตั้งค่า'sChildCtrl
$scope
ข้างในวิธี$scope
นี้ยังคงParentCtrl
เป็นขอบเขตของ $
ซอ
ฉันพยายามที่จะไม่ใช้this
ภายในฟังก์ชั่นที่กำหนดไว้ใน $ scope เพราะมันจะทำให้เกิดความสับสนซึ่ง $ scope ได้รับผลกระทบโดยเฉพาะอย่างยิ่งเมื่อพิจารณาว่า ng-repeat, ng-include, ng-switch และคำสั่งทั้งหมดสามารถสร้างขอบเขตลูกของตนเอง