加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – 在ui路由器解析过程中应用加载微调

发布时间:2020-12-17 08:37:23 所属栏目:安全 来源:网络整理
导读:$ routeProvider的resolve属性允许在渲染相应的视图之前执行一些作业。 如果我想显示一个微调器,而这些工作被执行,以增加用户体验怎么办? 实际上,否则用户将感觉到应用程序已经被阻塞,因为没有视图元素被显示一些毫秒 600。 当然,有一种方法来定义一个
$ routeProvider的resolve属性允许在渲染相应的视图之前执行一些作业。

如果我想显示一个微调器,而这些工作被执行,以增加用户体验怎么办?
实际上,否则用户将感觉到应用程序已经被阻塞,因为没有视图元素被显示一些毫秒> 600。

当然,有一种方法来定义一个全局的div元素从当前视图显示为了显示微调的感谢$ scope。$ rootChangeStart函数。
但我不想隐藏整个页面,只是一个差的旋转在中间。
我想要我的webapp的一些页面不同的方式加载显示。

我遇到了this interesting post包含我上面描述的确切问题:

That approach results in a horrible UI experience. The user clicks on
a button to refresh a list or something,and the entire screen gets
blanketed in a generic spinner because the library has no way of
showing a spinner just for the view(s) that are actually affected by
the state change. No thanks.

In any case,after I filed this issue,I realised that the “resolve”
feature is an anti-pattern. It waits for all the promises to resolve
then animates the state change. This is completely wrong – you want
your transition animations between states to run parallel to your data
loads,so that the latter can be covered up by the former.

For example,imagine your have a list of items,and clicking on one of
them hides the list and shows the item’s details in a different view.
If we have an async load for the item details that takes,on average,
400ms,then we can cover up the load almost entirely in most cases by
having a 300ms “leave” animation on the list view,and a 300ms “enter”
animation on the item details view. That way we provide a slicker feel
to the UI and can avoid showing a spinner at all in most cases.

However,this requires that we initiate the async load and the state
change animation at the same moment. If we use “resolve”,then the
entire async animation happens before the animation starts. The user
clicks,sees a spinner,then sees the transition animation. The whole
state change will take ~1000ms,which is too slow.

“Resolve” could be a useful way to cache dependencies between
different views if it had the option not to wait on promises,but the
current behaviour,of always resolving them before the state change
starts makes it almost useless,IMO. It should be avoided for any
dependencies that involve async loads.

我应该真的停止使用解决方案加载一些数据,而是开始在相应的控制器直接加载它们?所以我可以更新相应的视图,只要作业被执行,并在我想要的地方,在视图中,而不是全局。

你可以使用一个监听$ routeChangeStart的指令,例如当元素触发时显示元素:
app.directive('showDuringResolve',function($rootScope) {

  return {
    link: function(scope,element) {

      element.addClass('ng-hide');

      var unregister = $rootScope.$on('$routeChangeStart',function() {
        element.removeClass('ng-hide');
      });

      scope.$on('$destroy',unregister);
    }
  };
});

然后将它放在特定视图的加载器上,例如:

视图1:

<div show-during-resolve class="alert alert-info">
  <strong>Loading.</strong>
  Please hold.
</div>

视图2:

<span show-during-resolve class="glyphicon glyphicon-refresh"></span>

此解决方案(以及许多其他解决方案)的问题是,如果您浏览到从外部网站的路由之一,将没有加载以前的ng-view模板,所以您的页面可能在解决过程中为空白。

这可以通过创建一个将作为后备加载器的指令来解决。它将监听$ routeChangeStart并且只有在没有以前的路由时才显示加载器。

一个基本示例:

app.directive('resolveLoader',function($rootScope,$timeout) {

  return {
    restrict: 'E',replace: true,template: '<div class="alert alert-success ng-hide"><strong>Welcome!</strong> Content is loading,please hold.</div>',link: function(scope,element) {

      $rootScope.$on('$routeChangeStart',function(event,currentRoute,previousRoute) {
        if (previousRoute) return;

        $timeout(function() {
          element.removeClass('ng-hide');
        });
      });

      $rootScope.$on('$routeChangeSuccess',function() {
        element.addClass('ng-hide');
      });
    }
  };
});

后备加载器将放置在具有ng-view的元素之外:

<body>
  <resolve-loader></resolve-loader>
  <div ng-view class="fadein"></div>
</body>

演示全部:http://plnkr.co/edit/7clxvUtuDBKfNmUJdbL3?p=preview

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读