web-dev-qa-db-fra.com

Pourquoi ce simple AngularJS ng-show ne fonctionne-t-il pas?

Je n'arrive pas à comprendre pourquoi ma simple application AngularJS ne fonctionne pas comme prévu. "Chargement ..." est censé être caché et "Terminé!" devrait être montré après 1 seconde.

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);
}
40
darktideac

Vous devez indiquer à angular que vous avez mis à jour la var:

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

ou juste 

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

Pour ce faire, appelez $scope.$digest(); pour mettre à jour votre interface utilisateur.

12
TacoEater

Vous souhaitez utiliser la fonction apply() pour arrêter le chargement du message.

Cochez cette Demo jsFiddle **.

JavaScript:

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

J'espère que cela vous aidera!

6
Jay Patel

Vous devez utiliser $timeout et l'injecter dans votre contrôleur:

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

Fiddle démo

Edit: Removed $scope.apply(); comme suggéré par Salman

6
StarsSky

lorsque vous tirez un événement angulaire vers un autre objet comme setTimeout, vous devriez 

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

par exemple

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

peut ne pas fonctionner de la meilleure façon 

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

J'ai trouvé qu'une façon de contourner ng-show en ne vous évaluant pas comme vous le souhaitez est d'utiliser ng-class à la place.

 <div class="mycontent" data-ng-class="{'loaded': !loading}"> 

De cette façon, lorsque $ scope.loading n’est pas égal à true, la classe css 'chargée' sera ajoutée à l’élément . Il vous suffira alors d’afficher la fonction pour afficher/masquer le contenu.

.mycontent {
    display: none;
}

.loaded {
    display: block;
}
1
Glenn Nicoll

Je pense que le plus gros problème ici est que vous utilisez un modèle primitif. L'équipe angulaire recommande d'utiliser un objet pour lier votre modèle. Par exemple:

scope.model = {};
scope.model.loading = false;

Puis dans votre html:

<div class="text-center" ng-show="model.loading">

De cette façon, angular obtient une référence à un champ dans un objet au lieu d’une primitive désignée par une variable.

0
mariogarcia