Bagaimana saya bisa memberi tahu AngularJS untuk "menyegarkan"

168

Saya memiliki acara klik yang terjadi di luar lingkup direktif kustom saya, jadi alih-alih menggunakan atribut "ng-klik", saya menggunakan pendengar jQuery.click () dan memanggil fungsi di dalam lingkup saya seperti:

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

close () adalah fungsi sederhana yang terlihat seperti ini:

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

Dalam pandangan saya, saya memiliki elemen dengan "ng-show" terikat ke isOpen seperti ini:

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

Ketika debugging, saya menemukan bahwa close () dipanggil, isOpen sedang diperbarui ke false, tetapi tampilan AngularJS tidak memperbarui. Apakah ada cara saya bisa secara manual memberi tahu Angular untuk memperbarui tampilan? Atau ada pendekatan yang lebih "sudut" untuk memecahkan masalah ini yang tidak saya lihat?

Dustin
sumber

Jawaban:

315

Solusinya adalah menelepon ...

$scope.$apply();

... di callback acara jQuery saya.

Dustin
sumber
9
Tautan ini akan sangat membantu, saya pikir. jimhoskins.com/2012/12/17/angularjs-and-apply.html
Roman Sklyarov
6
bukankah seharusnya begitu $scope.$apply();?
ErichBSchulz
Anda dapat menggunakan $ scope atau scope, hanya saja perbedaan notasi tetapi hasilnya sama.
user1226868
4
@ErichBSchulz -Sering dalam arahan, saya melihat ruang lingkup digunakan tanpa $ yang saya percaya akan membedakan antara itu dan '$ lingkup' yang akan disuntikkan ke pengendali. Dalam controller, penting untuk referensi dengan $ scope sehingga Angular tahu ketergantungan apa yang harus disuntikkan, sedangkan dalam fungsi link direktif, selalu melewati 4 elemen yang sama secara ordinal dan tidak memerlukan nama spesifik (lingkup, elemen, attrs, controller ).
cchamberlain
30

Kenapa $applyharus dipanggil?

TL; DR : $applyharus dipanggil kapan pun Anda ingin menerapkan perubahan yang dibuat di luar dunia Angular.


Sekadar memperbarui jawaban Dustin , berikut adalah penjelasan tentang apa sebenarnya yang diterapkan $ dan mengapa ia bekerja.

$apply()digunakan untuk mengeksekusi ekspresi dalam AngularJS dari luar kerangka AngularJS. (Misalnya dari acara DOM browser, setTimeout, XHR atau perpustakaan pihak ketiga). Karena kita memanggil ke dalam kerangka AngularJS kita perlu melakukan siklus hidup lingkup yang tepat dari penanganan pengecualian , menjalankan jam tangan .

Angular memungkinkan nilai apa pun untuk digunakan sebagai target yang mengikat. Kemudian di akhir setiap pergantian kode JavaScript, ia memeriksa untuk melihat apakah nilainya telah berubah. Langkah itu yang memeriksa untuk melihat apakah ada nilai mengikat yang berubah sebenarnya memiliki metode, $scope.$digest()1 . Kami hampir tidak pernah memanggilnya secara langsung, karena kami menggunakan $scope.$apply()(yang akan memanggil $scope.$digest).

Angular hanya memonitor variabel yang digunakan dalam ekspresi dan apapun yang ada di dalam $watchkehidupan di dalam ruang lingkup. Jadi jika Anda mengubah model di luar konteks Angular, Anda perlu meminta $scope.$apply()agar perubahan tersebut disebarkan, jika tidak, Angular tidak akan tahu bahwa mereka telah diubah sehingga pengikatan tidak akan diperbarui 2 .

Mistalis
sumber
14

Menggunakan

$route.reload();

ingat untuk menyuntikkan $routeke controller Anda.

test30
sumber
5
Juga, ketika menggunakan ui-router, pastikan untuk menggunakan$state.reload()
Jeffrey Roosendaal
Ini sangat membantu untuk pengujian tangkapan layar kami! Kami mengejek negara tetapi kadang-kadang tidak selalu memiliki pengamat yang menonton perubahan, yang dapat mengakibatkan kegagalan membingungkan atau kegagalan intermiten. Tapi bisa memuat ulang ruang lingkup seperti ini membantu memerangi itu.
theblang