`

Angularjs: How to display loading-icon when using 'resolve' in $routeProvider?

阅读更多

 

The following code reads via a service and shows on the web page a list of 'page' objects for a specific 'page category' (string). Using the resolve object property in $routeProvider.when(), I am able to postpone updating the view until the new value is ready.

Two questions:

  1. When asking for a new page list, I want to show a loading-icon. How can I detect (in a non-hackish way) the event when the reading from server starts (and the loading-icon should be displayed)? I guess I could do something like $('.pages-loading-icon').show() in the service, but find that to be too gui dependent too placed in the service.

  2. When the new value is ready, I would like the old to fade out and the new to fade in. What is the 'angular' way to do this? I have tried to do it in the controller using $watch, but that causes the new value to be display shortly before the fadeout starts.

The code:

app.js:

$routeProvider.when('/:cat', { templateUrl: 'partials/view.html', controller: RouteCtrl, resolve: RouteCtrl.resolve});

controllers.js:

function RouteCtrl($scope, $routeParams, pages) {
        $scope.params = $routeParams;
        $scope.pages = pages;
    }

RouteCtrl.resolve={
    pages: function($routeParams, Pages){
        if($routeParams.hasOwnProperty('cat')){
            return Pages.query($routeParams.cat);
        }
    }
}

services.js: The last pages read is stored in currentPages and its category in lastCat.

factory('Pages', function($resource, $q, $timeout){
    return {
        res: $resource('jsonService/cat=:cat', {}, {
            query: {method:'GET', params:{cat:'cat'}, isArray:true}
        }),
        lastCat: null,
        currentPages: null,
        query: function(cat) {
            var res = this.res;
            if(cat != this.lastCat){
                var deferred = $q.defer();
                var p = res.query({'cat':cat}, function(){
                    deferred.resolve(p);
                });
                this.lastCat = cat;
                this.currentPages = deferred.promise;
            }
            return this.currentPages;
        }
    };
})

view.html

<ul >
    <li ng-repeat="page in pages">
        <a href="#{{params.cat}}/{{page.slug}}">{{page.title}}</a>
    </li>
</ul>
shareimprove this question
 

6 Answers

Not exactly sure whether this would work in your code as you have $resource integration. But it may be worth to look into angular events: $routeChangeStart and $routeChangeSuccess.

in html:

<span ng-show="isViewLoading"> loading the view... </span>

in controller (which defines the scope of the html above):

$scope.isViewLoading = false;
$scope.$on('$routeChangeStart', function() {
  $scope.isViewLoading = true;
});
$scope.$on('$routeChangeSuccess', function() {
  $scope.isViewLoading = false;
});
$scope.$on('$routeChangeError', function() {
  $scope.isViewLoading = false;
});
shareimprove this answer
 
    
I get each event triggered twice. Maybe because I have the same controller registered for multiple routes. Will look more into this, as it sound like the way to go. – Roar Skullestad Sep 13 '12 at 9:22
16  
Don't forget to stop loading on $routeChangeError – Jan Aug 19 '13 at 10:15
    
Miss to close span <span ng-show="isViewLoading"> loading the view... </span> – Fábio Paiva Jun 4 at 12:56 
    
It is a nice solution, but I'm not completely happy with it. If you have links from multiple views to a "slow" view, then you have to duplicate this event handling logic in every of your views. I would like to have it in a single place, for example, in the view we navigate to. Not sure if it's possible, since the target view is only rendered after resolve. – damluar Jun 11 at 11:19

The routing system for angular seems to be a bit limited.. 

This solved it for me: 
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

Also, about the events triggering twice: if you setup a route do map to "a/b/c" angular automatically sets up another route, "a/b/c/" (with trailing slash) to redirect to the first (and vice versa), and both trigger events. I just test for a presence of route parameters.

Regarding the limited condition of the routing sistem: there is this pull from angular, to extend it's capabilities.

shareimprove this answer
 

You can also use the ng-show directive. Simply check whether you model is empty and display a DOM subset like so:

    <!-- model not ready -->
    <div style="width: 200" ng-show="lines == ''">
      <div class="progress progress-striped active">
         <div class="bar" style="width: 0%;"></div>
      </div>
    </div>

    <!-- your model code -->
    <ul class="nav nav-tabs nav-stacked">
      <li ng-repeat="line in lines">
        {{line.Id}}
      </li>
    </ul>
shareimprove this answer
 

You will want to use the $rootScope because monitoring a controller's $scope is limited to the controller, and as it happens you're switching from one view (one controller) to another view (another controller). So it would make sense to have one-code-fit-all.

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ ... })

In that function set the $rootScope.isLoadingState which will display your loading indicator.

Then use

$rootScope.$on('$stateChangeSuccess', 
function(event, toState, toParams, fromState, fromParams){ ... })

To unset that variable.

Complete reference here

shareimprove this answer
 

I like the 'ng-show'... But the 'ui-if' of the Angular UI project is better IMHO.. Since remove the HTML code from the DOM...

<span ui-if = "isViewLoading"> loading the view... </span>

_e

shareimprove this answer
 

You can create a directive that will show based on a broadcast that you send before and after a service call, which you could put on $rootScope. So if you're calling a factory to handle dishing out generic POST/GET calls then right before the call you can call a function on $rootScope, such as "$rootScope.startLoading()" and when it finishes call "$rootScope.doneLoading()", where each of these methods broadcast an event for you to pick up on your directive. Then you just handle on your directive to catch the events, "scope.$on("startLoading", func(..." and have it insert/show a loading div template into the DOM and run, then also have a catch for done loading to remove/hide it.

That way you can have a nice general loading overlay.

shareimprove this answer
 
 
 
分享到:
评论

相关推荐

    pentaho-aggdesigner-algorithm-5.1.5-jhyde.tar

    解决 Cannot resolve org.pentaho:pentaho-aggdesigner-algorithm:5.1.5-jhyde jar放入D根目录执行: 以下命令加入本地maven库 mvn install:install-file -DgroupId=org.pentaho -DartifactId=pentaho-aggdesigner-...

    scala-java8-compat_2.11-0.7.0-API文档-中文版.zip

    赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...

    scala-java8-compat_2.11-0.7.0-API文档-中英对照版.zip

    赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...

    dingtalk-sdk-java.zip

    先把dingtalk-sdk-java安装到本地的 maven库里面, 再到pom.xml里添加一下。 ... 解压,再修改下面命令里面的路径后执行: mvn install:install-file -Dfile=/Users/dufuzhong/MyData/MyCode/demo/dingtalk-sdk-java/...

    详解AngularJs路由之Ui-router-resolve(预加载)

    AngularJS是一个非常流行的前端JavaScript框架,用于构建动态的Web应用。它提供了数据绑定、依赖注入、路由等多种功能。在AngularJS中,路由管理是实现单页面应用(SPA)的核心功能之一,通过它可以实现页面之间的...

    kafka-schema-registry-client-6.2.2.jar

    Could not resolve dependencies for project org.apache.flink:flink-avro-confluent-registry:jar:1.15.3: Could not find artifact io.confluent:kafka-schema-registry-client:jar:6.2.2 in maven 安装本地...

    api-asn1-api-1.0.0-M20-API文档-中文版.zip

    赠送jar包:api-asn1-api-1.0.0-M20.jar; 赠送原API文档:api-asn1-api-1.0.0-M20-javadoc.jar; 赠送源代码:api-asn1-api-1.0.0-M20-sources.jar; 赠送Maven依赖信息文件:api-asn1-api-1.0.0-M20.pom;...

    sentinel-transport-common-1.8.0-API文档-中文版.zip

    赠送jar包:sentinel-transport-common-1.8.0.jar; 赠送原API文档:sentinel-transport-common-1.8.0-javadoc.jar; 赠送源代码:sentinel-transport-common-1.8.0-sources.jar; 赠送Maven依赖信息文件:sentinel-...

    filters-2.0.235-1-API文档-中文版.zip

    赠送jar包:filters-2.0.235-1.jar; 赠送原API文档:filters-2.0.235-1-javadoc.jar; 赠送源代码:filters-2.0.235-1-sources.jar; 赠送Maven依赖信息文件:filters-2.0.235-1.pom; 包含翻译后的API文档:...

    netty-transport-native-unix-common-4.1.73.Final-API文档-中英对照版.zip

    赠送jar包:netty-transport-native-unix-common-4.1.73.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.73....

    lz4-java-1.8.0-API文档-中文版.zip

    赠送jar包:lz4-java-1.8.0.jar; 赠送原API文档:lz4-java-1.8.0-javadoc.jar; 赠送源代码:lz4-java-1.8.0-sources.jar; 赠送Maven依赖信息文件:lz4-java-1.8.0.pom; 包含翻译后的API文档:lz4-java-1.8.0-...

    pentaho-aggdesigner-algorithm-5.1.5-jhyde.jar

    可以解决,maven引入hive jar包时,hive Could not find artifact org.pentaho:pentaho-aggdesigner-algorithm:jar:5.1.5-jhyde 问题

    com.google.android.gms:play-gms:play-services:15.0.1

    Searched in the following locations: https://jcenter.bintray.com/com/google/android/gms/play-services-basement/15.0.1/play-services-basement-15.0.1.aar 最近google 出现不少问题 1、google 欧洲反垄断...

    netty-transport-classes-epoll-4.1.73.Final-API文档-中英对照版.zip

    赠送jar包:netty-transport-classes-epoll-4.1.73.Final.jar; 赠送原API文档:netty-transport-classes-epoll-4.1.73.Final-javadoc.jar; 赠送源代码:netty-transport-classes-epoll-4.1.73.Final-sources.jar;...

    netty-transport-native-unix-common-4.1.74.Final-API文档-中文版.zip

    赠送jar包:netty-transport-native-unix-common-4.1.74.Final.jar; 赠送原API文档:netty-transport-native-unix-common-4.1.74.Final-javadoc.jar; 赠送源代码:netty-transport-native-unix-common-4.1.74....

    jakarta.annotation-api-1.3.5-API文档-中文版.zip

    赠送jar包:jakarta.annotation-api-1.3.5.jar; 赠送原API文档:jakarta.annotation-api-1.3.5-javadoc.jar; 赠送源代码:jakarta.annotation-api-1.3.5-sources.jar; 赠送Maven依赖信息文件:jakarta.annotation...

    org.mongodb.spark:mongo-spark-connector_2.11:1.1.0

    mongodb-spark官方连接器,运行spark-submit --packages org.mongodb.spark:mongo-spark-connector_2.11:1.1.0可以自动下载,国内网络不容易下载成功,解压后保存到~/.ivy2目录下即可。

    javax.transaction-api-1.2-API文档-中文版.zip

    赠送jar包:javax.transaction-api-1.2.jar; 赠送原API文档:javax.transaction-api-1.2-javadoc.jar; 赠送源代码:javax.transaction-api-1.2-sources.jar; 赠送Maven依赖信息文件:javax.transaction-api-1.2....

    Practical Packet Analysis: Using Wireshark to Solve Real-World Network Problems

    Practical Packet Analysis: Using Wireshark to Solve Real-World Network Problems by Chris Sanders English | 28 Mar. 2017 | ASIN: B06XX74R1X | 368 Pages | AZW3 | 24.73 MB Wireshark is the world's most ...

    frocksdbjni-5.17.2-artisans-2.0-API文档-中文版.zip

    赠送jar包:frocksdbjni-5.17.2-artisans-2.0.jar; 赠送原API文档:frocksdbjni-5.17.2-artisans-2.0-javadoc.jar; 赠送源代码:frocksdbjni-5.17.2-artisans-2.0-sources.jar; 赠送Maven依赖信息文件:...

Global site tag (gtag.js) - Google Analytics