В эти дни я пытался реализовать способ показать пользователям переход между страницами в приложении, для этого я искал в google и для невероятного, что кажется, я мог бы найти решение в angular. Но после длительных исследований мне удалось создать лучшее решение для этой задачи.
Итак, отвечая на вопрос, вынесенный в заголовок статьи, ответом для создания загрузчика страниц являются события Router, всякий раз, когда происходит изменение, такое как переход на другую страницу, передача параметров URL и другие, связанные с маршрутом, происходит событие, затем для реализации решения нам нужно искать нужные события.
Чтобы решить эту задачу, я разделил объяснение на четыре основных пункта: приложение, логика маршрута и загрузчик.
1. Приложение
На этом этапе мы создадим приложение, которое будем использовать для реализации загрузчика, и для этого воспользуемся angular CLI.
ng new page-loader --routing
Приведенная выше команда запускает новый проект angular с именем page-loader с начальными настройками маршрутов.
Далее мы создадим три новых маршрута для приложения, страница-один, страница-два и страница-три будут лениво загружены. Стоит отметить, что создаваемые маршруты должны быть лениво загружены, как по соображениям производительности, так и для того, чтобы пример работал так, как ожидается. Для этого мы создадим новые маршруты с помощью команд, приведенных ниже:
ng generate module page-one --route page-one --module app.module
ng generate module page-two --route page-two --module app.module
ng generate module page-three --route page-three --module app.module
После успешного выполнения всех этих команд структура вашего приложения должна выглядеть следующим образом:
А вот так выглядит app-routing.module.ts
:
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
const routes: Routes = [
{path: '', component: HomeComponent},
{
path: 'second-page',
loadChildren: () => import('./second-page/second-page.module').then(m => m.SecondPageModule)
},
{
path: 'third-page',
loadChildren: () => import('./third-page/third-page.module').then(m => m.ThirdPageModule)
},
{
path: 'first-page',
loadChildren: () => import('./first-page/first-page.module').then(m => m.FirstPageModule)
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
;
Имея уже организованное приложение, вы можете добавить немного текста и стилей на страницы, чтобы придать им более приятный вид, или вы также можете взять коды, которые я использовал для этого проекта, прямо с моего github.
2. Логика
Теперь, когда приложение уже создано, мы сосредоточимся на его работе, для этого мы будем слушать события angular router в самом верхнем элементе приложения, app.component.ts
. Angular router имеет события в своем жизненном цикле, от начала навигации до ее окончания, как вы можете увидеть по ссылке, но для нашего случая мы рассмотрим только три из этих событий:
- NavigationStart: Происходит при запуске новой навигации;
- NavigationEnd: Происходит, когда навигация успешно завершена;
- NavigationError: Возникает при ошибке во время навигации.
Ответ для загрузчика страниц находится в вышеуказанных событиях, слушая их, мы можем динамически изменять состояние нашего приложения, то есть когда мы начинаем навигацию, мы показываем загрузчик, и он может быть удален после завершения или ошибки во время навигации. С учетом этого наш app.component.ts
выглядит следующим образом:
import { Component } from '@angular/core'
import { Event, NavigationEnd, NavigationError, NavigationStart, Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.less']
})
export class AppComponent {
loading = false;
constructor(private router: Router){
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
this.loading = true;
}
if (event instanceof NavigationEnd || event instanceof NavigationError) {
this.loading = false;
}
})
}
}
;
3. Погрузчик
Как я уже говорил, загрузчик будет находиться в самом верхнем компоненте приложения, поэтому он не будет удален из домена во время навигации, а будет управляться самым верхним компонентом, app.component.ts
. Поэтому мы поместим наш загрузчик непосредственно в app.component.html
.
<!-- div para mostrar a animação de loading --
<div *ngIf="loading" class="page-loading"></div>
<app-navbar></app-navbar>
<div class="container">
<router-outlet></router-outlet>
</div>
Переменная загрузки была создана в компоненте приложения, и она изменяется в зависимости от состояния маршрута, поэтому во время навигации будет отображаться загрузчик страницы, а после завершения навигации будет отображаться то же самое. Теперь у нас почти все готово для нашего загрузчика страницы, не хватает только анимации, и для этого я создал анимацию загрузчика прогресса, вдохновленный youtube. Но вы можете использовать любой из них по своему выбору для отображения на экране во время загрузки страницы.
.page-loading
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 10px;
z-index: 1234;
background-color: transparent;
&::after {
content: "";
position: absolute;
left: 0;
background-color: #77befc;
width: 100%;
height: 100%;
animation: load 3s;
}
}
@keyframes load {
0% {width: 0;}
10% {width: 20%;}
25% {width: 40%;}
50% {width: 60%;}
75% {width: 75%;}
100% {width: 100%;}
}
Окончательный результат
Заключительные соображения
Поскольку пример приложения слишком прост, может быть трудно увидеть загрузчик в действии, но если ваше приложение больше и сложнее, это решение поможет вам обеспечить лучший опыт для ваших пользователей, поскольку теперь у них будет приятная обратная связь, когда они просматривают страницы в вашем приложении.
Пройдя этот путь, я надеюсь, что этот результат помог вам так же, как и мне.
Посмотрите на мое портфолио kelven.dev, там есть много интересного.