Angular js - 显示/隐藏每个新路由加载gif

时间:2014-02-02 16:19:17

标签: javascript angularjs toggle loading routes

我正试图在每条新路线上切换(隐藏/显示)加载gif,所以我的逻辑是:

  • routeChangeStart = show loading gif
  • routeChangeSuccess =隐藏加载gif

这是我的代码:

//ANGULAR
app.run(function($rootScope) {

   $rootScope.layout = {};
   $rootScope.layout.loading = false; 

   $rootScope.$on('$routeChangeStart', function() {

      //show loading gif
      $rootScope.layout.loading = true;

   });

   $rootScope.$on('$routeChangeSuccess', function() {

      //hide loading gif
      $rootScope.layout.loading = false;

   });

   $rootScope.$on('$routeChangeError', function() {

       //hide loading gif
       alert('wtff');
       $rootScope.layout.loading = false;
   });
});

// HTML

<img src="img/loading.gif" ng-hide="!layout.loading"/>

这很奇怪,因为这适用于3/4路线已更改,然后在更改路线时停止工作:O

它可能是什么?

感谢@Rob Sedgwick:http://plnkr.co/edit/ZpkgRhEAoUGlnXjbLb8b

,这是一个实际的例子

2 个答案:

答案 0 :(得分:22)

简短回答 $rootScope.layout.loading按预期更改。但是如果加载了模板,浏览器就没有时间使更改可见。

答案很长 :如果您在console.log听众中放置$on输出,则会看到$routeChangeStart事件触发,加载模板,然后$routeChangeSuccess触发。在引擎盖下发生以下情况:

  • $routeChangeStart开火
  • $rootScope.layout.loading变为true
  • 模板以异步方式加载
  • DOM已更新
  • 浏览器呈现加载gif

稍后(xhr请求返回)

  • 模板已加载
  • $routeChangeSuccess开火
  • $rootScope.layout.loading变为false
  • DOM已更新
  • 浏览器不再显示gif

如果缓存了tmeplates会发生什么: - $routeChangeStart发生火灾 - $rootScope.layout.loading变为true - $routeChangeSuccess发生火灾 - $rootScope.layout.loading变为false - 更新DOM(但这与以前的状态相同)

正如您所看到的,浏览器无法呈现新状态,因为正在运行的脚本不会中断,无法为浏览器提供呈现DOM的时间。如果尚未加载模板,则ajax请求会停止脚本执行,并为浏览器提供渲染DOM的时间。

如何解决这个问题?

您可以使用timeout来提供浏览器时间来更新DOM:

$rootScope.$on('$routeChangeSuccess', function () {
    console.log('$routeChangeSuccess');
    //hide loading gif
    $timeout(function(){
      $rootScope.layout.loading = false;
    }, 200);
});

以下是您的解决方案:http://plnkr.co/edit/MkREo0Xpz5SUWg0lFCdu?p=preview

答案 1 :(得分:3)

(有点太多不能发表评论)

我设置了代码,看到加载变量每次都没有更新,并且是由于模板缓存,我猜不会触发'RouteChange'。

禁用模板缓存会让您的代码每次都运行..

app.run(function($rootScope, $location, $anchorScroll, $routeParams,$templateCache) {

   $rootScope.$on('$viewContentLoaded', function() {
       $templateCache.removeAll();
    });

   ....