puelo
puelo

Reputation: 5977

AngularJs on finished rendering

I am trying for hours, but with no luck at all. I have an angularjs application where i want to present the user with a loading spinner as long as the page is not fully loaded (rendered). Especially between state changes, because the click is registered, but nothing is happening right away. Thus the user is getting no feedback if it is actually loading or not. My application is requesting some data through ajax when the controller is getting executed. I have already tried different solutions:

  1. Using $stateChangeStart and $viewContentLoaded. This approach does work fine if the views are loaded for the first time, but fires too early for every subsequent state change. This has to do with the caching of templates. Every time the viewContentLoaded is fired the template is cached.

  2. Using a directive with $timeout. This does work very well on the first load-up if i attach it to the body of my html document. But since i am using nested views/controllers the directive is not called again when i switch between states. It is once again fired to early when i attach the directive to the ui-viewelement.

Are there any alternatives? Am i doing something wrong? Is it even possible?

Thanks

Upvotes: 0

Views: 2443

Answers (4)

user11142863
user11142863

Reputation:

For someone.

<div style="visibility: hidden;">
    {{MyVarAfterLoad = true}}
</div>

Upvotes: 0

null
null

Reputation: 7926

Have a look at angular-block-ui, which is a module that takes care of displaying a loading indicator. Blocking can be done on the whole page or on individual elements. Behind the scenes it monitors http requests and determines if a block should be active (it ignores cached http requests).

Upvotes: 0

iH8
iH8

Reputation: 28638

Have you tried using the resolve object?

You can use resolve to provide your controller with content or data that is custom to the state. resolve is an optional map of dependencies which should be injected into the controller.

https://github.com/angular-ui/ui-router/wiki#resolve

Using resolve allows you to fetch your data before the controller is initialized. That way when your controller executes and $viewContentLoaded is fired you can be sure that your data is available:

$stateProvider.state('myState', {
    templateUrl: 'template.html',
    controller: function($scope, myData){
        $scope.myData = myData;
    },
    resolve:{
        myData:  function($http){
            return $http({method: 'GET', url: '/myUrl'})
                .then (function (data) {
                    return doSomeStuffFirst(data);
                }
            );
        }
    }
});

I bet when using resolve and your first option (using $routeChangeStart and $viewContentLoaded to set and remove your spinner) things will work a lot better than it does now.

Upvotes: 1

Exziled
Exziled

Reputation: 493

Create a div in your webapp where you want the spinner to display.

use an ng-show="loading"

Before your request set $scope.loading = true; then create an AngularJS promise which (using a .then() or .finally()) and in this .finally() put $scope.loading = false;

This way it shows your spinner while it's loading and when it's finally done it sets it to false which keeps it from showing.

Upvotes: 0

Related Questions