user4266661
user4266661

Reputation:

AngularJS: showing/hiding elements during UI update

I'm trying to solve an issue that's making my angular app look odd. I have an $http.get which initializes the model. Since it takes a couple of seconds to resolve against the server, I want to display an information tag until it's done.

However, what's happening is that the tag gets hidden before the rest of the UI is finished updating.

I've tried various approaches based on googling, but so far without success. Here's my current markup:

<div ng-controller="endCtrl" ng-show="model.groups.length > 0">
    <div ng-repeat="group in model.groups" ng-show="group.Endorsements.length > 0">
        <h3>{{group.Title}}</h3>
        <div ng-repeat="endorsement in group.Endorsements">
            <p>
                <span class="endorsement-name">{{endorsement.Name}}</span><span class="footnote" ng-show="endorsement.Role != null">, {{endorsement.Role}}</span>
            </p>
        </div>
    </div>
</div>

And here's the controller:

app.controller( '@ViewBag.AngularController', function( $scope, $http, $q, $timeout ) {
    $scope.model = {
        groups: [],
    };

    $http.get( "/Home/GetEndorsements" )
    .then(
        function( resp ) {
            $scope.model.groups = resp.data;
            return $q.defer().resolve( true );
        },
        function( resp ) {
            $scope.model.groups = [];
            return $q.defer().resolve( true );
        }
    )
    .then( function( resp ) {
        $timeout;
    } )
} );

I included the call to $timeout because something I read suggested it would not run until the UI was finished updating. But again, that's not working.

Update

My problem was the result of a bone-headed mistake: the "please wait" element was outside the scope of the controller:

<p ng-show="model.groups.length <= 0">
    Initializing, please wait...
</p>
<div ng-controller="endCtrl">
    <div ng-show="model.groups.length > 0">

so, naturally, the ng-show directive on it always returned false, hiding the element as soon as it was compiled into the DOM.

Moving the item into the scope of the controller solved the problem.

Upvotes: 0

Views: 65

Answers (1)

Okazari
Okazari

Reputation: 4597

You can see a plunker working like you want.

You should try a more "regular" way of using $http.

My Controller

$scope.model = {
        groups: [],
        gettingData: true,
    };

    $http.get( "data.json" )
    .success(function(resp){
        $scope.model.groups = resp.data;
        $scope.model.gettingData = false;
    }).error(function(resp) {
        $scope.model.groups = [];
        $scope.model.gettingData = false;
    });

My view

<body ng-app="myApp" ng-controller="myController">
    <span ng-show="model.gettingData">Loading !!!!!</span>
    <div ng-show="!model.gettingData">
        <div ng-repeat="group in model.groups" ng-show="group.Endorsements.length > 0">
            <h3>{{group.Title}}</h3>
            <div ng-repeat="endorsement in group.Endorsements">
                <p>
                    <span class="endorsement-name">{{endorsement.Name}}</span><span class="footnote" ng-show="endorsement.Role != null">, {{endorsement.Role}}</span>
                </p>
            </div>
        </div>
    </div>  
  </body>

Tell me if it work as you expected. Actually your logic seems good, but i'm a bit confused with your way of using $http.

Upvotes: 1

Related Questions