ฉันจะบอก AngularJS ให้“ รีเฟรช” ได้อย่างไร


168

ฉันมีเหตุการณ์คลิกที่เกิดขึ้นนอกขอบเขตของคำสั่งที่กำหนดเองดังนั้นแทนที่จะใช้แอตทริบิวต์ "ng-click" ฉันใช้ jQuery.click () listener และเรียกใช้ฟังก์ชันภายในขอบเขตของฉันดังนี้:

$('html').click(function(e) {
  scope.close();
);

close () เป็นฟังก์ชั่นง่าย ๆ ที่มีลักษณะดังนี้:

scope.close = function() {
  scope.isOpen = false;
}

ในมุมมองของฉันฉันมีองค์ประกอบที่มี "ng-show" ถูกผูกไว้กับ isOpen ดังนี้:

<div ng-show="isOpen">My Div</div>

เมื่อตรวจแก้จุดบกพร่องฉันพบว่ามีการเรียกว่า close () isOpen กำลังได้รับการอัปเดตเป็นเท็จ แต่มุมมอง AngularJS ไม่ได้อัปเดต มีวิธีที่ฉันสามารถบอก Angular ให้อัปเดตมุมมองด้วยตนเองได้หรือไม่ หรือมีวิธี "เชิงมุม" มากขึ้นในการแก้ไขปัญหาที่ฉันไม่เห็นหรือไม่

คำตอบ:


315

วิธีแก้ไขคือโทร ...

$scope.$apply();

... ในการโทรกลับกิจกรรม jQuery ของฉัน


9
ลิงค์นี้จะเป็นประโยชน์ฉันคิดว่า jimhoskins.com/2012/12/17/angularjs-and-apply.html
Roman Sklyarov

6
ไม่ควรที่จะเป็น$scope.$apply();อย่างไร
ErichBSchulz

คุณสามารถใช้ทั้ง $ scope หรือ scope มันเป็นเพียงความแตกต่างของสัญกรณ์ แต่ผลลัพธ์จะเหมือนกัน
1226868

4
@ErichBSchulz - บ่อยครั้งในคำสั่งฉันเห็นขอบเขตที่ใช้โดยไม่มี $ ซึ่งฉันเชื่อว่ามีแนวโน้มที่จะแยกความแตกต่างระหว่างมันและ '$ scope' ที่ได้รับการฉีดเข้าไปในตัวควบคุม ในตัวควบคุมมันเป็นสิ่งสำคัญที่จะอ้างอิงโดย $ scope ดังนั้น Angular รู้ว่าการพึ่งพาการฉีดในขณะที่ในฟังก์ชั่นการเชื่อมโยงคำสั่งมันมักจะผ่าน 4 องค์ประกอบเดียวกันตามลำดับและไม่ต้องการชื่อเฉพาะ (ขอบเขตองค์ประกอบ attrs ตัวควบคุม )
cchamberlain

30

ทำไม$applyต้องเรียกว่า

TL; DR : $applyควรถูกเรียกเมื่อใดก็ตามที่คุณต้องการใช้การเปลี่ยนแปลงที่เกิดขึ้นนอกโลกเชิงมุม


เพียงเพื่อปรับปรุง@ คำตอบของดัสตินและนี่คือคำอธิบายของสิ่งที่ $ ใช้ที่ไม่ตรงและทำไมมันทำงาน

$apply()จะใช้ในการดำเนินการแสดงออกใน AngularJS จากนอกกรอบ AngularJS (ตัวอย่างเช่นจากเหตุการณ์ DOM ของเบราว์เซอร์, setTimeout, XHR หรือไลบรารีบุคคลที่สาม) เพราะเราจะเรียกเข้าไปในกรอบ AngularJS เราจำเป็นต้องดำเนินการวงจรชีวิตขอบเขตที่เหมาะสมของ การจัดการข้อยกเว้น , รันนาฬิกา

เชิงมุมช่วยให้ค่าใด ๆ ที่จะใช้เป็นเป้าหมายที่มีผลผูกพัน จากนั้นในตอนท้ายของการเปิดโค้ด JavaScript ใด ๆ ก็จะตรวจสอบเพื่อดูว่ามีการเปลี่ยนแปลงค่า ขั้นตอนที่ตรวจสอบเพื่อดูว่าค่าที่มีผลผูกพันใด ๆ $scope.$digest()ที่มีการเปลี่ยนแปลงจริงมีวิธีที่ 1 เราแทบจะไม่เคยเรียกมันว่าโดยตรงเพราะเราใช้$scope.$apply()แทน (ซึ่งจะเรียก$scope.$digest)

เชิงมุมจะตรวจสอบตัวแปรที่ใช้ในการแสดงออกและทุกสิ่งที่$watchอยู่ภายในขอบเขต ดังนั้นถ้าคุณมีการเปลี่ยนแปลงที่อยู่นอกรูปแบบของบริบทเชิงมุมคุณจะต้องเรียก$scope.$apply()สำหรับการเปลี่ยนแปลงเหล่านั้นจะได้รับการแพร่กระจายมิฉะนั้นเชิงมุมจะไม่ทราบว่าพวกเขาได้รับการเปลี่ยนแปลงจึงมีผลผูกพันจะไม่ได้รับการปรับปรุง2


14

ใช้

$route.reload();

อย่าลืมที่จะฉีดเข้าไป$routeในคอนโทรลเลอร์ของคุณ


5
นอกจากนี้เมื่อใช้ ui-router ต้องแน่ใจว่าได้ใช้$state.reload()
Jeffrey Roosendaal

นี่เป็นประโยชน์อย่างมากสำหรับการทดสอบภาพหน้าจอของเรา! เราเยาะเย้ยรัฐ แต่บางครั้งก็ไม่จำเป็นต้องมีผู้เฝ้าดูที่เฝ้าดูการเปลี่ยนแปลงซึ่งอาจส่งผลให้เกิดความล้มเหลวที่ทำให้สับสนหรือความล้มเหลวเป็นระยะ ๆ แต่ความสามารถในการโหลดขอบเขตเช่นนี้ช่วยต่อสู้ได้
theblang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.