2014-04-05 5 views
37

Ich kann nicht herausfinden, warum meine einfache AngularJS App nicht wie vorgesehen funktioniert. "Loading ..." soll versteckt sein und "Done!" sollte nach 1 Sekunde angezeigt werden.Warum funktioniert diese einfache AngularJS ng-show nicht?

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

Dieser Beitrag war hilfreich, aber der Titel eignet sich nicht zum googeln. –

Antwort

56

Sie müssen Winkel sagen, dass Sie die var aktualisiert:

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

oder nur

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

Alles klar, nur mit AngularJS zu beginnen, wusste nicht über anwenden. Danke für die Hilfe.Ich habe diese Antwort gewählt - weil ich in meiner echten App (nicht in der jsfiddle) einen Fehler mit dem Ansatz von StarsSky hatte, $ scope.apply() zu verwenden. – darktideac

+2

Sie erhalten den Fehler mit der Antwort von StarSky, weil das $ -Zeitlimit einen Digest-Zyklus startet und $ apply versucht, ein zweites zu starten, aber Sie können nicht mehr als 1 Digest gleichzeitig haben. – Deepsy

+28

Das ist das Richtige, aber warum? Wenn ich $ scope mit dem neuen Wert aktualisiere, ist diese $ scope-Eigenschaft nicht bereits auf der $ watch-Liste, und sollte das DOM automatisch über die Magie der bidirektionalen Bindung aktualisiert werden? Nicht verstehen, warum $ scope. $ Apply() notwendig ist. –

6

Sie müssen $timeout benutzen und es in Ihrem Controller zu injizieren:

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

Fiddle demo

Edit: entfernt $scope.apply(); als @Salman

vorgeschlagen
+1

Wenn Sie bereits $ timeout verwenden, brauchen Sie $ scope.apply(); Weil eckig sicherstellen, dass der Wert mit apply aktualisiert wird. – Salman

+1

$ apply(), nicht. Apply() –

6

Sie apply() Funktion Stopp verwenden möchten Laden Nachricht.

Überprüfen Sie diese Demo jsFiddle **.

JavaScript:

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

Hope this Sie helfen würde!

+0

Wow. $ apply hat für mich funktioniert! – Sung

11

Ein schöner Weg, dies zu tun, ist durch $scope.$digest(); Aufruf UI

+0

Ich mag diesen "Trick" nicht, aber arbeitete für mich (mein '$ scope' var wird in einen Bibliotheksrückruf aktualisiert). Vielen Dank! – dbautistav

2

wenn Feuer Winkel Ereignis auf ein anderes Objekt wie SetTimeout bearbeiten Sie

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

zum Beispiel

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

verwenden sollten funktioniert möglicherweise nicht am besten

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

Ich habe festgestellt, dass eine Möglichkeit, um ng-show zu umgehen und nicht so zu evaluieren, wie Sie es wollen, die Verwendung von ng-class ist.

Auf diese Weise, wenn $ scope.loading nicht gleich wahr ist, wird die CSS-Klasse 'loaded' zum Element hinzugefügt. Dann brauchen Sie nur eine, um die CSS-Klasse zu verwenden, um den Inhalt ein-/auszublenden.

.mycontent { 
    display: none; 
} 

.loaded { 
    display: block; 
}