Come posso dire ad AngularJS di "aggiornare"


168

Ho un evento click che si verifica al di fuori dell'ambito della mia direttiva personalizzata, quindi invece di utilizzare l'attributo "ng-click", sto usando un listener jQuery.click () e sto chiamando una funzione all'interno del mio ambito in questo modo:

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

close () è una semplice funzione simile a questa:

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

A mio avviso, ho un elemento con "ng-show" associato a isOpen in questo modo:

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

Durante il debug, sto scoprendo che viene chiamato close (), isOpen viene aggiornato a false, ma la vista AngularJS non si aggiorna. C'è un modo in cui posso dire manualmente ad Angular di aggiornare la vista? O esiste un approccio più "angolare" per risolvere questo problema che non vedo?

Risposte:


315

La soluzione era chiamare ...

$scope.$apply();

... nel mio callback dell'evento jQuery.



6
non dovrebbe essere $scope.$apply();?
ErichBSchulz,

Puoi usare sia $ scope che scope, è solo una differenza di notazione ma risulta la stessa.
user1226868

4
@ErichBSchulz-Spesso nelle direttive, vedo l'ambito utilizzato senza il $ che credo possa differenziare tra esso e il '$ scope' che viene iniettato nei controller. Nei controller, è importante fare riferimento per $ scope in modo che Angular sappia quale dipendenza iniettare, mentre in una funzione di collegamento direttiva, passa sempre gli stessi 4 elementi in ordinale e non richiede un nome specifico (scope, element, attrs, controller ).
cchamberlain,

30

Perché $applydovrebbe essere chiamato?

TL; DR : $applydovrebbe essere chiamato ogni volta che si desidera applicare le modifiche apportate al di fuori del mondo angolare.


Solo per aggiornare la risposta di @Dustin , ecco una spiegazione di cosa esattamente fa $ applicare e perché funziona.

$apply()viene utilizzato per eseguire un'espressione in AngularJS dall'esterno del framework AngularJS. (Ad esempio da eventi DOM del browser, setTimeout, XHR o librerie di terze parti). Poiché stiamo invocando il framework AngularJS, dobbiamo eseguire il corretto ciclo di vita dell'ambito della gestione delle eccezioni , eseguendo gli orologi .

Angolare consente di utilizzare qualsiasi valore come target vincolante. Quindi alla fine di ogni giro di codice JavaScript, controlla se il valore è cambiato. Il passaggio che controlla se sono stati modificati valori di associazione ha effettivamente un metodo, $scope.$digest()1 . Non lo chiamiamo quasi mai direttamente, come $scope.$apply()invece usiamo (che chiamerà $scope.$digest).

Angolare monitora solo le variabili utilizzate nelle espressioni e qualsiasi cosa all'interno di una $watchvita all'interno dell'ambito. Pertanto, se si sta modificando il modello al di fuori del contesto angolare, sarà necessario richiedere la $scope.$apply()propagazione di tali modifiche, altrimenti Angular non saprà che sono state modificate, pertanto l'associazione non verrà aggiornata 2 .


14

Uso

$route.reload();

ricordati di iniettare $routenel tuo controller.


5
Inoltre, quando si utilizza ui-router, assicurarsi di utilizzare$state.reload()
Jeffrey Roosendaal

Questo è stato molto utile per i nostri test di screenshot! Deridiamo lo stato ma a volte non abbiamo necessariamente osservatori che osservano i cambiamenti, il che può causare errori confusi o guasti intermittenti. Ma essere in grado di ricaricare l'ambito in questo modo aiuta a combatterlo.
theblang
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.