近期的项目中需要给页面加载时增加一个Loading动画,于是我在项目的rootController中新增了一个全局可用的基于angular material dialog的简单loading动画,如下:
ts:
$window["pcLoadingShow"] = function(){ $mdDialog.show({ templateUrl: "pages/common-components/pcLoading.html" }); }
$window["pcLoadingHide"] = function(){ $mdDialog.hide(); }
template:
<div id="pcLoadingDialogContainer"> <md-dialog id="loading_icon_container" style="min-height: 100px;"> <md-dialog-content> <div id="loading_icon"></div> </md-dialog-content> </md-dialog> </div>
界面中最里层div的背景是一个GIF动图,除此之外,dialog默认的遮罩层是灰黑色并半透明,测试觉得并不能起到真正的作用,所以需要把默认的遮罩层修改掉,但又不能直接去css中替换其样式。于是在最外层嵌套一层div,css如下:
#pcLoadingDialogContainer{ width: 100%; height: 100%; background: #fff; }
接下来美滋滋的去使用这个loading图,我在页面controller constructor的初始化方法中直接使用$window["pcLoadingShow"](),接下来在调用页面内容接口成功或者失败后均$window["pcLoadingHide"]()。运行之后的效果是静态页面优先加载出来,随后loading图才展示,显示不尽人意。因为项目中使用的是angular ui router,查询相关资料后想到另一种解决方案:在路由触发之前(静态页加载之前)就把loading图show出来。具体如下:
一、首先需要了解angular ui router的几个事件:
1.state change events 状态改变事件(所有这些事件都是在$rootScope
作用域触发)
- $stateChangeStart - 当模板开始解析之前触发
$rootScope.$on('$stateChangeStart',function(event, viewConfig){ });
- $stateChangeSuccess - 当模板解析完成后触发
$rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ })
2.view load events 视图加载事件
- $viewContentLoading - 当视图开始加载,DOM渲染完成之前触发,该事件将在
$scope
链上广播此事件。
$scope.$on('$viewContentLoading', function(event, viewConfig){ });
- $viewContentLoaded - 当视图加载完成,DOM渲染完成之后触发,视图所在的
$scope
发出该事件。
$scope.$on('$viewContentLoading',$scope.$on('$viewContentLoaded',function(event){ });
二、在rootController中使用$stateChangeStart事件,并在对应state加载之前引入loading图即可,如下:
$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ if(toParams.moduleName==="该视图对应的module name"){ $window["pcLoadingShow"](); } })
除此之外,感觉$viewContentLoading事件也可以实现,但是尝试了没有成功,希望哪位朋友可以讲解下,后续会继续完善angular ui router相关的内容。