我的场景如下。我有一个菜单,有多个选项。每个菜单都应该根据用户权限(已经解决(显示,大多数菜单项被封装为模块,并且大多数模块都是延迟加载的,所以当用户第一次单击菜单项时,它会加载(到目前为止一切正常(,现在我的要求是,为了提供更好的用户体验, 我需要在用户在加载延迟加载模块时单击菜单项后显示活动指示器。
到目前为止,我尝试使用来自Angular Router的canActive,canLoad,canActivateChild接口,但没有运气。
有什么想法吗?
您可以侦听两个路由器事件:
-
RouteConfigLoadStart
-
RouteConfigLoadEnd
它们在加载延迟加载的模块时触发。与标准路由器事件(如 NavigationStart
(相比,使用这些事件的优势在于它们不会在每次路由更改时触发。
在您的根应用程序组件中收听它们以显示/隐藏您的微调器。
app.component.ts
import { Router, RouteConfigLoadStart, RouteConfigLoadEnd } from '@angular/router';
...
export class AppComponent implements OnInit {
loadingRouteConfig: boolean;
constructor (private router: Router) {}
ngOnInit () {
this.router.events.subscribe(event => {
if (event instanceof RouteConfigLoadStart) {
this.loadingRouteConfig = true;
} else if (event instanceof RouteConfigLoadEnd) {
this.loadingRouteConfig = false;
}
});
}
}
app.component.html
这里只是一个简单的字符串,但您可以使用微调器组件。
<router-outlet></router-outlet>
<ng-container *ngIf="loadingRouteConfig">Loading route config...</ng-container>
我在 Angular v4.2.3 中使用这种方法
你可以这样做
- 在应用程序组件中.html
<div class="main-loader" *ngIf="loading"> <div class="cssload-container" > <div class="cssload-whirlpool"></div> </div> </div>
-
在应用程序中。
import { Router, NavigationStart, NavigationEnd } from '@angular/router'; loading:boolean = false; constructor(private router:Router) { router.events.subscribe(event => { if(event instanceof NavigationStart) { this.loading = true; console.log("event started") }else if(event instanceof NavigationEnd) { this.loading = false; console.log("event end") } // NavigationEnd // NavigationCancel // NavigationError // RoutesRecognized }); }
-
在 CSS 中任何加载动画
希望这对你有用。
你可以使用 CSS !
<routler-outlet></routler-outlet>
<div class='.loader>
Just, wait a sec ! I'm loading
</div>
在您的模板中
router-outlet + .loader {
opacity : 1;
}
.loader {
opacity : 0;
}
然后你可以用HTML/CSS创建花哨的微调器
可以在加载第一个路由时单击指向其他延迟加载路由的链接。这就是为什么我们需要计算正在加载的路由:
app.component.ts
'''
export class AppComponent {
currentlyLoadingCount = this._router.events.scan((c, e) => this._countLoads(c, e), 0);
constructor(private _router: Router) { }
private _countLoads(counter: number, event: any): number {
if (event instanceof RouteConfigLoadStart) return counter + 1;
if (event instanceof RouteConfigLoadEnd) return counter - 1;
return counter;
}
'''
app.component.html
<ng-container *ngIf="currentlyLoadingCount | async">Loading route config...</ng-container>
需要与IE11兼容(和处理(的人来说,接受的答案不起作用,因为IE11在从一个模块切换到另一个模块时不会呈现加载器,所以我做了一个(不是很优雅但可以工作(解决方法:
在我的菜单中,项目切换单击事件:
public navigate(url: string) {
this.configurationService.loading = true; //service variable linked with html loader
//let's give time to tortoise IE11 to render loader before navigation...
let obj = this;
setTimeout(function()
{
obj.router.navigateByUrl(url);
}, 1);
}