ทำไมเราถึงใช้ $ rootScope. $ ออกอากาศใน AngularJS?


109

พยายามหาข้อมูลพื้นฐานของ AngularJS $rootScope.$broadcastแต่เอกสาร AngularJS ไม่ได้ช่วยอะไรมาก พูดง่ายๆว่าทำไมเราถึงใช้สิ่งนี้?

นอกจากนี้ภายในเทมเพลตHot Towelของ John Papa ยังมีฟังก์ชันที่กำหนดเองในโมดูลทั่วไปที่ชื่อ$broadcast:

function $broadcast() {
    return $rootScope.$broadcast.apply($rootScope, arguments);
}

ฉันไม่เข้าใจว่านี่กำลังทำอะไรอยู่ ดังนั้นนี่คือคำถามพื้นฐานสองสามข้อ:

1) $rootScope.$broadcastทำอะไร?

2) อะไรคือความแตกต่างระหว่าง$rootScope.$broadcastและ$rootScope.$broadcast.apply?




$rootScope.$broadcast.apply()ใช้เพราะถ้าคุณต้องการส่งผ่านargumentsวัตถุพิเศษไปยังฟังก์ชันอื่นคุณต้องใช้apply()(ซึ่งตรงข้ามกับcall()) นอกจากนี้ในการเชื่อมโยง @ Blackhole ไปยังเพจ MDN argumentsในใช้คุณยังอาจตรวจสอบรายการบน
Scott Schupbach

คำตอบ:


97
  1. อะไร$rootScope.$broadcastทำอย่างไร

    $rootScope.$broadcastกำลังส่งเหตุการณ์ผ่านขอบเขตแอปพลิเคชัน ขอบเขตใด ๆ ของเด็ก app $scope.$on()ที่สามารถจับมันใช้ง่าย:

    มีประโยชน์อย่างยิ่งในการส่งเหตุการณ์เมื่อคุณต้องการเข้าถึงขอบเขตที่ไม่ใช่พาเรนต์โดยตรง (เช่นสาขาของพาเรนต์)

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

  2. อะไรคือความแตกต่างระหว่าง$rootScope.$broadcast& $rootScope.$broadcast.apply?

    บางครั้งคุณต้องใช้apply()โดยเฉพาะอย่างยิ่งเมื่อทำงานกับคำสั่งและไลบรารี JS อื่น ๆ อย่างไรก็ตามเนื่องจากฉันไม่รู้ฐานรหัสนั้นฉันจึงไม่สามารถบอกได้ว่าเป็นเช่นนั้นหรือไม่


11
จับ$rootScope.$onความทรงจำรั่วไหลได้ดี สิ่งนี้ใช้กับคำตอบที่ยอมรับเช่นกันเนื่องจากตัวควบคุมมักจะเรียกสิ่งที่hiEventServiceเขาสร้างขึ้น
adamdport

ตัวอย่างที่คุณจะใช้$broadcastกับอะไร$broadcast.apply()
แขกรับเชิญ

$ rootScope $ broadcast ส่งเหตุการณ์ไปยังผู้ฟังทุกคนไม่เพียง แต่ผู้ฟังจากขอบเขตเด็กเท่านั้น ขอบเขต $ การออกอากาศ $ จำกัด เหตุการณ์เป็นขอบเขตย่อย
Geert Bellemans

157

$rootScope โดยทั่วไปทำหน้าที่เป็นผู้ฟังเหตุการณ์และผู้มอบหมายงาน

เพื่อตอบคำถามว่าใช้อย่างไรจึงใช้ร่วมกับrootScope.$on;

$rootScope.$broadcast("hi");

$rootScope.$on("hi", function(){
    //do something
});

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

แนวทางปฏิบัติที่ดีที่สุดคือสร้างบริการสำหรับเหตุการณ์ที่กำหนดเองแต่ละรายการที่คุณต้องการฟังหรือออกอากาศ

.service("hiEventService",function($rootScope) {
    this.broadcast = function() {$rootScope.$broadcast("hi")}
    this.listen = function(callback) {$rootScope.$on("hi",callback)}
})

4
ขอบคุณ @itcouldevenbeabout บรรทัดนี้ไม่ได้เรียกใช้ตรรกะเดียวกันในการแนบเหตุการณ์กับ $ rootScope ทั่วโลกหรือไม่? function () {$ rootScope. $ broadcast ("hi")} ที่คุณพูดถึงเป็นการปฏิบัติที่ไม่ดีหรือไม่?
Nexus23

11
การใช้บริการเพื่อออกอากาศและแนบผู้ฟังสำหรับเหตุการณ์หนึ่ง ๆ เพื่อหลีกเลี่ยงสถานการณ์ที่คุณไม่แน่ใจว่าใครกำลังฟังอยู่ เป็นที่ชัดเจนว่าส่วนประกอบ
ใดบ้างที่

4
เมื่อเพิ่งค้นพบความแตกต่างระหว่าง $ emit และ $ broadcast ฉันมีแนวโน้มที่จะบอกว่าการปล่อยเหตุการณ์นั้นจะดีกว่าซึ่งเป็นวิธีที่คุณทำให้เหตุการณ์นั้นก่อให้เกิดมลพิษในขอบเขตที่เล็กที่สุดเท่าที่จะเป็นไปได้ (โดยหลักการแล้วบริการจะมี เป็นขอบเขตของตัวเอง แต่ฉันไม่คิดว่าจะเป็นไปได้?)
Brondahl

3
-1. ฉันไม่เห็นว่าการแยกในบริการดีกว่าการออกอากาศเพียงอย่างเดียว อย่างไรก็ตามควรใช้ขอบเขตส่วนตัวของตัวเองในบริการดีกว่า และใช้ $ emit ได้ดีกว่าไม่ใช่ $ broadcast นอกจากนี้บริการที่เสนอของคุณไม่สนับสนุนข้อโต้แย้งของเหตุการณ์ ที่แย่กว่านั้นคือไม่รองรับการยกเลิกการสมัคร บาปมหันต์สำหรับ $ rootScope
alpha-mouse

3
การไม่มีการยกเลิกการสมัครจะทำลายคำตอบนี้สำหรับฉัน หากคุณโทรhiEventService.listen(callback)จากคอนโทรลเลอร์ผู้ฟังจะยังคงอยู่แม้ว่าคอนโทรลเลอร์จะถูกทำลายไปแล้วก็ตาม ความจำรั่ว! การเชื่อมโยงกับขอบเขตตัวควบคุม$scope.$on("hi",callback)มาพร้อมกับการล้างข้อมูลอัตโนมัติ
adamdport

32

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

ขอบเขตรูทถ่ายทอดเหตุการณ์:

$rootScope.$broadcast("myEvent");

ขอบเขตของเด็ก ๆ สามารถฟังเหตุการณ์:

$scope.$on("myEvent",function () {console.log('my event occurred');} );

ทำไมเราถึงใช้ $ rootScope $ broadcast? คุณสามารถใช้$watchเพื่อฟังการเปลี่ยนแปลงตัวแปรและเรียกใช้ฟังก์ชันเมื่อสถานะตัวแปรเปลี่ยนไป อย่างไรก็ตามในบางกรณีคุณเพียงแค่ต้องการเพิ่มเหตุการณ์ที่ส่วนอื่น ๆ ของแอปพลิเคชันสามารถรับฟังได้โดยไม่คำนึงถึงการเปลี่ยนแปลงสถานะตัวแปรขอบเขต เมื่อ$broadcastเป็นประโยชน์


19

ส่งผ่านข้อมูล !!!

ฉันสงสัยว่าทำไมไม่มีใครพูดถึงว่า$broadcastยอมรับพารามิเตอร์ที่คุณสามารถส่งผ่านObjectที่จะได้รับโดย $onใช้ฟังก์ชันโทรกลับ

ตัวอย่าง:

// the object to transfert
var myObject = {
    status : 10
}

$rootScope.$broadcast('status_updated', myObject);
$scope.$on('status_updated', function(event, obj){
    console.log(obj.status); // 10
})

8

$ rootScope. $ broadcast ทำอะไร?

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

ในทำนองเดียวกันเรามี $ rootScope $ emit ข้อแตกต่างเพียงอย่างเดียวคืออดีตถูกจับโดย $ scope $ on ในขณะที่หลังถูกจับโดย $ rootScope $ on เท่านั้น

ดูตัวอย่าง: - http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

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