【问题标题】:Angular js - show/hide loading gif every new routeAngular js - 显示/隐藏每条新路线的加载 gif
【发布时间】:2014-02-26 02:02:42
【问题描述】:

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

  • routeChangeStart = 显示加载 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

【问题讨论】:

  • 嗨,有兴趣在这里查看答案。在这里,我在“点击”上启动“加载器”(更改路线的链接)并将其隐藏在模板/控制器内部(例如,当它加载时)。有效,但这是更整洁/干燥的方式。
  • @RobSedgwick 等不及回答了,哈哈,我认为有一个 var 切换 gif 很酷,让我们看看是否有人可以提供帮助;)
  • @RobSedgwick 如果可以,请自行尝试,我不知道为什么它不起作用,它适用于 3/4 路线更改然后停止工作:(
  • 虽然您的方法有效,但我个人认为使用请求/响应拦截器非常适合。

标签: javascript angularjs toggle loading routes


【解决方案1】:

简短回答$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);
});

这是您使用此解决方案的 plunkr:http://plnkr.co/edit/MkREo0Xpz5SUWg0lFCdu?p=preview

【讨论】:

    【解决方案2】:

    (评论有点多)

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

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

    app.run(function($rootScope, $location, $anchorScroll, $routeParams,$templateCache) {
    
       $rootScope.$on('$viewContentLoaded', function() {
           $templateCache.removeAll();
        });
    
       ....
    

    【讨论】:

    • mmmm 你知道是否可以只从缓存中删除元素吗? :P 因为这似乎现在可以工作,但我想缓存内容:P
    • 可能有办法对“routeChanged”进行“硬”检查——但我不知道那是什么。对不起。禁用缓存以显示加载指示器感觉有点不对劲。为什么不通过 ng-click 链接触发您自己的路由更改 - 通过预路由路由您的路由 - 可以这么说(只是猜测想法)
    • 我只是想让这项工作只是因为我不明白为什么它不起作用:D 然后确定我是否无法像这样得到它,我会寻找其他一些解决方法:P 谢谢你;)+1
    • 更新了@sbaaaang,看起来它也需要注入'$route',试试看。感谢您向我介绍这种新方式。
    • 试过了,但有时它仍然停止工作:(我试图在plnkr.co/YSsFTyZ521tU9OJoW38c这里做一个plunkr作为一个活生生的例子,但我无法让它工作:/
    猜你喜欢
    • 2018-05-25
    • 2018-01-01
    • 1970-01-01
    • 2011-07-25
    • 2015-06-10
    • 1970-01-01
    • 2017-01-04
    • 1970-01-01
    相关资源
    最近更新 更多