2014-04-05 8 views
37

Non riesco a capire perché la mia semplice app AngularJS non funzioni come previsto. "Caricamento in corso ..." dovrebbe essere nascosto e "Fatto!" dovrebbe essere mostrato dopo 1 secondo.Perché questo semplice nG-show di AngularJS non funziona?

html:

<div ng-app> 
    <div ng-controller="TestCtrl"> 
     <div class="text-center" ng-show="loading"> 
      <h1>Loading...</h1> 

    </div> 
     <div class="text-center" ng-show="!loading"> 
      <h1>Done!</h1> 

     </div> 
    </div> 
</div> 

Javascript:

function TestCtrl($scope) { 
    $scope.loading = true; 
    setTimeout(function() { 
     $scope.loading = false; 
    }, 1000); 
} 
+3

Questo post è stato utile ma il titolo non si presta ad essere googlable. –

risposta

56

Devi dire angolare che è stata aggiornata la var:

function TestCtrl($scope) { 
    $scope.loading = true; 
    setTimeout(function() { 
     $scope.$apply(function(){ 
      $scope.loading = false; 
     }); 
    }, 1000); 
} 

o semplicemente

function TestCtrl($scope, $timeout) { 
    $scope.loading = true; 
    $timeout(function() { 
     $scope.loading = false; 
    }, 1000); 
} 
+1

Allright thanks, appena iniziato con AngularJS, non sapeva dell'applicazione. Grazie per l'aiuto.Ho scelto questa risposta, perché nella mia vera app (non nel jsfiddle), ho riscontrato un errore nell'approccio di StarsSky all'utilizzo di $ scope.apply(). – darktideac

+2

Stai ottenendo l'errore con la risposta di StarSky, perché il timeout $ avvia un ciclo di digest e $ apply sta tentando di iniziare un secondo, ma non puoi avere più di 1 digest in corso alla volta. – Deepsy

+28

Questa è la cosa giusta da fare, ma perché? Se sto aggiornando $ scope con il nuovo valore, la proprietà $ scope non è già presente nell'elenco $ watch e dovrei aggiornare automaticamente il DOM tramite la magia del binding a due vie? Non capisco perché $ scope. $ Apply() è necessario. –

6

È necessario utilizzare $timeout e iniettarlo nel controllore:

function TestCtrl($scope, $timeout) { 
    $scope.loading = true; 
    $timeout(function() { 
     $scope.loading = false; 
    }, 1000); 
} 

Fiddle demo

Edit: rimosso $scope.apply(); come @Salman suggerito

+1

se si utilizza già $ timeout, non è necessario utilizzare $ scope.apply(); perché angolare assicurarsi che il valore venga aggiornato utilizzando apply. – Salman

+1

$ apply(), not .apply() –

6

Si desidera utilizzare apply() funzione per arresto caricamento messaggio.

Controllare questo Demo jsFiddle **.

JavaScript:

function TestCtrl($scope) { 
    $scope.loading = true; 
    setTimeout(function() { 
     $scope.$apply(function(){ 
      $scope.loading = false; 
     }); 
    }, 1000); 
} 

Spero che questo sarebbe aiutarvi!

+0

Wow. $ applicare ha funzionato per me! – Sung

11

un modo migliore per farlo è chiamando $scope.$digest(); per aggiornare l'interfaccia utente

+0

Non mi piace questo "trucco", ma ha funzionato per me (la mia variabile '$ scope' viene aggiornata in una richiamata della libreria). Grazie! – dbautistav

2

quando il fuoco evento angolare ad un altro oggetto, come setTimeout si dovrebbe usare

$scope.$apply(function(){ 
    $scope.loading = false; 
}); 

ad esempio

var loading={ 
    show:function(){ 
     $scope.loading=true 
    }, 
    hide:function(){ 
     $scope.loading=false 
    } 
} 

potrebbe non funzionare in modo migliore

var loading={ 
     show:function(){ 
      $scope.$apply(function(){ 
       $scope.loading=true 
      }); 
     }, 
     hide:function(){ 
      $scope.$apply(function(){ 
       $scope.loading=false 
      }); 
     } 
    } 
0

Ho trovato che un modo per aggirare il funzionamento di ng-show e non di valutare come si vuole è usare invece ng-class.

In questo modo, quando $ scope.loading non è uguale a true, la classe css "caricata" verrà aggiunta all'elemento. Quindi hai solo bisogno di usare la classe css per mostrare/nascondere il contenuto.

.mycontent { 
    display: none; 
} 

.loaded { 
    display: block; 
}