ความแตกต่างระหว่าง $ scope และ $ rootScope


91

ใครช่วยอธิบายความแตกต่างระหว่าง $ scope และ $ rootScope ได้บ้าง?

ฉันคิด

ขอบเขต $:

เราสามารถรับคุณสมบัติของ ng-model ในตัวควบคุมเฉพาะได้จากหน้าเฉพาะโดยใช้สิ่งนี้


$ rootScope

เราสามารถรับคุณสมบัติ ng-model ทั้งหมดในคอนโทรลเลอร์จากหน้าใดก็ได้โดยใช้สิ่งนี้


ถูกต้องหรือไม่ หรืออย่างอื่น?


@CodeError! สิ่งที่คุณหมายถึงลิงก์นั้นไม่ได้ช่วยในคำถามของฉันมี $ scope $ root ไม่ใช่ $ rootScope

$ rootScope อยู่ที่ด้านบนสุดของลำดับชั้นของขอบเขตทั้งหมดในแอปเชิงมุมของคุณ
Angad

คำตอบ:


88

"$ rootScope" เป็นอ็อบเจ็กต์หลักของอ็อบเจ็กต์เชิงมุม "$ ขอบเขต" ทั้งหมดที่สร้างในเว็บเพจ

ใส่คำอธิบายภาพที่นี่

$ ขอบเขตถูกสร้างขึ้นด้วยng-controllerในขณะที่ $ rootscope ถูกสร้างด้วยng-app.

ใส่คำอธิบายภาพที่นี่


69

ความแตกต่างที่สำคัญคือความพร้อมใช้งานของคุณสมบัติที่กำหนดให้กับวัตถุ $scopeไม่สามารถใช้คุณสมบัติที่กำหนดด้วยภายนอกคอนโทรลเลอร์ซึ่งกำหนดไว้ในขณะที่คุณสมบัติที่กำหนดด้วย$rootScopeสามารถใช้ได้ทุกที่

ตัวอย่าง: หากในตัวอย่างด้านล่างคุณแทนที่$rootScopeด้วย$scopeคุณสมบัติแผนกจะไม่ถูกเติมจากคอนโทรลเลอร์ตัวแรกในตัวที่สอง

angular.module('example', [])
  .controller('GreetController', ['$scope', '$rootScope',
    function($scope, $rootScope) {
      $scope.name = 'World';
      $rootScope.department = 'Angular';
    }
  ])
  .controller('ListController', ['$scope',
    function($scope) {
      $scope.names = ['Igor', 'Misko', 'Vojta'];
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="example">
  <div class="show-scope-demo">
    <div ng-controller="GreetController">
      Hello {{name}}!
    </div>
    <div ng-controller="ListController">
      <ol>
        <li ng-repeat="name in names">{{name}} from {{department}}</li>
      </ol>
    </div>
  </div>
</body>


18

ตามคู่มือขอบเขตของนักพัฒนาของ Angular :

แอปพลิเคชัน Angular แต่ละตัวมีขอบเขตรูทเดียว แต่อาจมีขอบเขตย่อยหลายขอบเขต แอปพลิเคชันสามารถมีได้หลายขอบเขตเนื่องจากคำสั่งบางคำสั่งสร้างขอบเขตย่อยใหม่ (ดูเอกสารคำสั่งเพื่อดูว่าคำสั่งใดสร้างขอบเขตใหม่) เมื่อสร้างขอบเขตใหม่จะถูกเพิ่มเป็นลูกของขอบเขตหลัก สิ่งนี้จะสร้างโครงสร้างต้นไม้ที่ขนานกับ DOM ที่พวกมันแนบมา

ทั้งตัวควบคุมและคำสั่งมีการอ้างอิงถึงขอบเขต แต่ไม่ใช่ซึ่งกันและกัน การจัดเรียงนี้จะแยกคอนโทรลเลอร์ออกจากคำสั่งและจาก DOM นี่เป็นจุดสำคัญเนื่องจากทำให้คอนโทรลเลอร์ดูไม่เชื่อเรื่องพระเจ้าซึ่งช่วยปรับปรุงเรื่องราวการทดสอบของแอปพลิเคชันได้อย่างมาก


13

$rootScopeมีให้ใช้งานทั่วโลกไม่ว่าคุณจะอยู่ในคอนโทรลเลอร์ใดในขณะที่$scopeตัวควบคุมปัจจุบันมีให้ใช้งานและเป็นรุ่นย่อย


3

ในทางอื่นเราสามารถดูสิ่งนี้ได้ $rootScopeเป็นสากลในขณะที่$scopeอยู่ในท้องถิ่น เมื่อControllerถูกกำหนดให้กับเพจดังนั้นจึง$scopeสามารถใช้ตัวแปรได้ที่นี่เพราะมันผูกกับคอนโทรลเลอร์นี้ แต่เมื่อเราต้องการแบ่งปันคุณค่าของมันไปยังคอนโทรลเลอร์หรือบริการอื่น ๆ ก็$rootScopeจะถูกนำมาใช้ (** มีวิธีอื่นเราสามารถแชร์ค่าข้ามกันได้ แต่ในกรณีนี้เราต้องการใช้$rootScope)

คำถามที่สองของคุณเกี่ยวกับวิธีที่คุณกำหนดคำสองคำนั้นถูกต้อง

สุดท้ายนี้โปรดใช้$rootScopeด้วยความระมัดระวัง เช่นเดียวกับวิธีที่คุณใช้ตัวแปรส่วนกลางอาจเป็นความเจ็บปวดในการดีบักและคุณอาจเปลี่ยนตัวแปรส่วนกลางโดยบังเอิญที่ใดที่หนึ่งภายในตัวจับเวลาหรือสิ่งที่ทำให้การอ่านของคุณไม่ถูกต้อง


2

ทุกแอปพลิเคชันจะมี rootScope เดียวอย่างน้อยหนึ่งตัวและวงจรการใช้งานจะเหมือนกับแอปและคอนโทรลเลอร์ทุกตัวสามารถมีขอบเขตของตัวเองซึ่งจะไม่แชร์กับผู้อื่น

ดูบทความนี้:

https://github.com/angular/angular.js/wiki/Understand-Scopes


2

ฉันขอแนะนำให้คุณอ่านเอกสารเชิงลึกเชิงลึกอย่างเป็นทางการสำหรับขอบเขต เริ่มต้นที่ส่วน 'ลำดับชั้นขอบเขต':

https://docs.angularjs.org/guide/scope

โดยพื้นฐานแล้ว $ rootScope และ $ scope ระบุส่วนเฉพาะของ DOM ที่อยู่ภายใน

  • ดำเนินการเชิงมุม
  • ตัวแปรที่ประกาศเป็นส่วนหนึ่งของ $ rootScope หรือ $ scope นั้นพร้อมใช้งาน

ทุกสิ่งที่เป็นของ $ rootScope สามารถใช้ได้ทั่วโลกในแอป Angular ของคุณในขณะที่ทุกสิ่งที่เป็นของ $ ขอบเขตจะมีอยู่ในส่วนของ DOM ที่ขอบเขตนั้นใช้

$ rootScope ถูกนำไปใช้กับองค์ประกอบ DOM ที่เป็นองค์ประกอบรูทสำหรับแอพ Angular (ดังนั้นชื่อ $ rootScope) เมื่อคุณเพิ่มคำสั่ง ng-app ลงในองค์ประกอบของ DOM สิ่งนี้จะกลายเป็นองค์ประกอบหลักของ DOM ที่ $ rootScope พร้อมใช้งาน กล่าวอีกนัยหนึ่งคุณสมบัติและอื่น ๆ ของ $ rootScope จะพร้อมใช้งานตลอดทั้งแอปพลิเคชัน Angular ของคุณ

ขอบเขต $ Angular (และตัวแปรและการดำเนินการทั้งหมด) มีให้สำหรับ DOM บางส่วนภายในแอปพลิเคชันของคุณ โดยเฉพาะขอบเขต $ สำหรับคอนโทรลเลอร์เฉพาะจะพร้อมใช้งานในส่วนของ DOM ที่ใช้ตัวควบคุมนั้น ๆ (โดยใช้คำสั่ง ng-controller) โปรดทราบว่าคำสั่งบางอย่างเช่น ng-repeat เมื่อนำไปใช้ภายในส่วนหนึ่งของ DOM ที่มีการใช้คอนโทรลเลอร์สามารถสร้างขอบเขตลูกของขอบเขตหลัก - ภายในคอนโทรลเลอร์เดียวกัน - คอนโทรลเลอร์ไม่จำเป็นต้องมีเพียงขอบเขตเดียว

หากคุณดู HTML ที่สร้างขึ้นเมื่อคุณเรียกใช้แอป Angular คุณสามารถดูได้อย่างง่ายดายว่าองค์ประกอบ DOM ใด 'มี' ขอบเขตเนื่องจาก Angular จะเพิ่มขอบเขตระดับชั้นบนองค์ประกอบใด ๆ ที่มีการใช้ขอบเขต (รวมถึงองค์ประกอบราก ของแอปซึ่งมี $ rootScope)

อย่างไรก็ตามเครื่องหมาย '$' ที่จุดเริ่มต้นของ $ scope และ $ rootScope เป็นเพียงตัวระบุใน Angular สำหรับสิ่งที่ Angular สงวนไว้

โปรดทราบว่าการใช้ $ rootScope สำหรับการแบ่งปันตัวแปร ฯลฯ ระหว่างโมดูลและคอนโทรลเลอร์ไม่ถือว่าเป็นแนวทางปฏิบัติที่ดีที่สุด นักพัฒนา JavaScript พูดถึงการหลีกเลี่ยง 'มลพิษ' ของขอบเขตทั่วโลกโดยการแบ่งปันตัวแปรที่นั่นเนื่องจากอาจมีข้อขัดแย้งในภายหลังหากมีการใช้ตัวแปรชื่อเดียวกันที่อื่นโดยที่นักพัฒนาไม่ทราบว่ามีการประกาศไว้ใน $ rootScope แล้ว ความสำคัญของสิ่งนี้จะเพิ่มขึ้นตามขนาดของแอปพลิเคชันและทีมที่กำลังพัฒนา ตามหลักการแล้ว $ rootScope จะมีเฉพาะค่าคงที่หรือตัวแปรคงที่ซึ่งตั้งใจให้สอดคล้องกันตลอดเวลาในแอป วิธีที่ดีกว่าในการแบ่งปันสิ่งต่างๆในโมดูลอาจเป็นการใช้บริการและโรงงานซึ่งเป็นอีกหัวข้อหนึ่ง!


2

ทั้งสองเป็นวัตถุสคริปต์ Java และความแตกต่างแสดงโดยแผนภาพด้านล่าง

ใส่คำอธิบายภาพที่นี่

NTB:
แอปพลิเคชั่นเชิงมุมตัวแรกพยายามค้นหาคุณสมบัติของโมเดลหรือฟังก์ชันใด ๆ ใน $ ขอบเขตหากไม่พบคุณสมบัติใน $ ขอบเขตให้ค้นหาในขอบเขตหลักในลำดับชั้นบน หากยังไม่พบคุณสมบัติในลำดับชั้นบนดังนั้นเชิงมุมจะพยายามหาค่าใน $ rootscope


1

รูปแบบใหม่เช่นAngularJS Styleguide ของ John Papaกำลังบอกว่าเราไม่ควรใช้$scopeเพื่อบันทึกคุณสมบัติของหน้าปัจจุบันเลย แต่เราควรใช้controllerAs with vmวิธีการที่มุมมองเชื่อมโยงกับวัตถุตัวควบคุมเอง จากนั้นใช้ตัวแปรการจับสำหรับสิ่งนี้เมื่อใช้ไวยากรณ์ของ controllerAs เลือกชื่อตัวแปรที่สอดคล้องกันเช่น vm ซึ่งย่อมาจาก ViewModel

คุณยังคงต้องการ$scopeความสามารถในการรับชม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.