Показывать индикатор активности при загрузке лениво загруженного модуля в Angular 2
Мой сценарий таков. У меня есть меню с несколькими вариантами. Каждое меню должно отображаться в зависимости от прав пользователя (уже решено), большинство пунктов меню инкапсулированы в виде модулей, и большинство модулей загружаются с отложенной загрузкой, поэтому, когда пользователь щелкает первый раз в пункте меню, он загружается (до все работает хорошо), теперь мое требование состоит в том, чтобы для лучшего взаимодействия с пользователем мне нужно было отображать индикатор активности после того, как пользователь щелкнет по пункту меню и загружается лениво загруженный модуль.
До этого я пытался использовать интерфейсы CanActive, canLoad, canActivateChild от Angular Router, но безуспешно,
Есть идеи?
5 ответов
Вы можете прослушать два события маршрутизатора:
RouteConfigLoadStart
RouteConfigLoadEnd
Они срабатывают, когда загружается ленивый загруженный модуль. Преимущество использования этих по сравнению со стандартными событиями маршрутизатора, такими как NavigationStart
в том, что они не будут стрелять при каждом изменении маршрута.
Слушайте их в своем корневом AppComponent, чтобы показать / скрыть свой счетчик.
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
Ты можешь сделать это так
- в app.component.html
<div class="main-loader" *ngIf="loading"> <div class="cssload-container" > <div class="cssload-whirlpool"></div> </div> </div>
в app.component.ts
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 не отображает загрузчик при переключении с одного модуля на другой, поэтому я сделал (не очень элегантный, но работающий) обходной путь:
В моем menuItem переключатель щелчка события:
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);
}