Создание многостраничных приложений в Angular: учебный материал

Создание многостраничных приложений в Angular: учебный материал

Angular является одним из самых популярных фреймворков для разработки веб-приложений. Он предоставляет мощные инструменты для создания сложных, масштабируемых и производительных приложений. В этом учебном материале будет рассмотрен процесс создания многостраничных приложений в Angular, начиная с основ и заканчивая продвинутыми техниками.

Содержание:

  • Введение в Angular
  • Настройка окружения для разработки
  • Основы Angular: компоненты, модули и сервисы
  • Routing в Angular
  • Создание многостраничного приложения
  • Работа с формами
  • HTTP-запросы и взаимодействие с API
  • Аутентификация и авторизация
  • Оптимизация производительности
  • Тестирование Angular-приложений
  • Развертывание приложения

Введение в Angular

Angular — это платформа и фреймворк для создания клиентских приложений на HTML и TypeScript. Он реализует основные и дополнительные функции как набор библиотек TypeScript, которые импортируются в приложения.

Ключевые особенности Angular:

  • Компонентная архитектура
  • Шаблоны на основе HTML
  • Зависимость от инъекций
  • Модульность
  • Встроенный роутинг
  • Поддержка TypeScript

Angular предоставляет разработчикам мощный инструментарий для создания сложных веб-приложений. Его архитектура позволяет легко масштабировать проекты и поддерживать их на протяжении длительного времени.

Настройка окружения для разработки

Перед началом работы с Angular необходимо настроить окружение для разработки. Это включает в себя установку Node.js, npm (Node Package Manager) и Angular CLI (Command Line Interface).

Шаги по настройке окружения:

  1. Установить Node.js и npm с официального сайта nodejs.org
  2. Открыть терминал и выполнить команду: npm install -g @angular/cli
  3. Проверить установку, выполнив команду: ng version

После успешной установки Angular CLI, можно приступать к созданию нового проекта.

Создание нового проекта Angular:

Для создания нового проекта необходимо выполнить следующую команду в терминале:

ng new my-angular-app

Angular CLI задаст несколько вопросов о конфигурации проекта, после чего создаст базовую структуру приложения.

Основы Angular: компоненты, модули и сервисы

Angular основан на концепции компонентов, модулей и сервисов. Понимание этих базовых элементов необходимо для эффективной разработки приложений.

Компоненты

Компоненты являются основными строительными блоками пользовательского интерфейса в Angular-приложениях. Каждый компонент состоит из:

  • HTML-шаблона, определяющего представление
  • Класса TypeScript, управляющего данными и логикой
  • CSS-стилей, определяющих внешний вид

Пример простого компонента:

 import { Component } from '@angular/core'; @Component({ selector: 'app-hello', template: '

{{ greeting }}

', styles: ['h1 { color: blue; }'] }) export class HelloComponent { greeting = 'Hello, Angular!'; }

Модули

Модули в Angular используются для организации приложения и его функциональности. Они группируют связанные компоненты, директивы, сервисы и другие файлы. Каждое Angular-приложение имеет как минимум один корневой модуль, обычно называемый AppModule.

Пример модуля:

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; @NgModule({ imports: [BrowserModule], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } 

Сервисы

Сервисы в Angular используются для организации и совместного использования бизнес-логики, моделей данных, функций для работы с сетью и других операций, не связанных напрямую с представлением. Они внедряются в компоненты с помощью механизма внедрения зависимостей.

Пример сервиса:

 import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class DataService { getData() { return ['Item 1', 'Item 2', 'Item 3']; } } 

Routing в Angular

Routing является ключевым элементом в создании многостраничных приложений на Angular. Он позволяет определять различные пути (URL) и связывать их с компонентами, создавая навигацию по приложению.

Читайте также  Приложение TenChat для Android вошло в топ-20 самых скачиваемых

Настройка маршрутизации

Для настройки маршрутизации в Angular необходимо выполнить следующие шаги:

  1. Импортировать RouterModule в главный модуль приложения
  2. Определить маршруты
  3. Добавить <router-outlet> в шаблон
  4. Создать навигацию

Пример конфигурации маршрутов:

 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } 

Навигация в приложении

Для создания навигации в Angular-приложении используется директива routerLink. Она позволяет создавать ссылки на различные маршруты.

Пример навигационного меню:

 <nav> <ul> <li><a routerLink="/">Home</a></li> <li><a routerLink="/about">About</a></li> </ul> </nav> <router-outlet></router-outlet> 

Создание многостраничного приложения

Теперь, когда рассмотрены основные концепции Angular и настройка маршрутизации, можно приступить к созданию многостраничного приложения.

Структура проекта

Типичная структура многостраничного Angular-приложения может выглядеть следующим образом:

 src/ app/ home/ home.component.ts home.component.html home.component.css about/ about.component.ts about.component.html about.component.css contact/ contact.component.ts contact.component.html contact.component.css shared/ header/ header.component.ts header.component.html header.component.css footer/ footer.component.ts footer.component.html footer.component.css app.component.ts app.component.html app.component.css app.module.ts app-routing.module.ts index.html styles.css main.ts 

Создание компонентов

Для каждой страницы приложения создается отдельный компонент. Это можно сделать с помощью Angular CLI:

 ng generate component home ng generate component about ng generate component contact 

Каждая команда создаст новый компонент с соответствующими файлами (.ts, .html, .css).

Настройка маршрутизации

В файле app-routing.module.ts необходимо определить маршруты для каждого компонента:

 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { AboutComponent } from './about/about.component'; import { ContactComponent } from './contact/contact.component'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'about', component: AboutComponent }, { path: 'contact', component: ContactComponent }, { path: '**', redirectTo: '' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } 

Создание навигации

В главном компоненте приложения (app.component.html) создается навигационное меню:

 <header> <nav> <ul> <li><a routerLink="/">Home</a></li> <li><a routerLink="/about">About</a></li> <li><a routerLink="/contact">Contact</a></li> </ul> </nav> </header> <main> <router-outlet></router-outlet> </main> <footer> <p>&copy; 2024 My Angular App</p> </footer> 

Работа с формами

Формы являются важной частью многих веб-приложений. Angular предоставляет два подхода к работе с формами: реактивные формы и формы на основе шаблонов.

Реактивные формы

Реактивные формы предоставляют модельно-ориентированный подход к обработке входных данных формы. Они более масштабируемы и подходят для сложных сценариев.

Пример реактивной формы:

 import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-contact', template: ` <form [formGroup]="contactForm" (ngSubmit)="onSubmit()"> <input formControlName="name" placeholder="Name"> <input formControlName="email" placeholder="Email"> <textarea formControlName="message" placeholder="Message"></textarea> <button type="submit" [disabled]="!contactForm.valid">Send</button> </form> ` }) export class ContactComponent implements OnInit { contactForm: FormGroup; constructor(private fb: FormBuilder) {} ngOnInit() { this.contactForm = this.fb.group({ name: ['', Validators.required], email: ['', [Validators.required, Validators.email]], message: ['', Validators.required] }); } onSubmit() { if (this.contactForm.valid) { console.log(this.contactForm.value); } } } 

Формы на основе шаблонов

Формы на основе шаблонов используют директивы для создания и манипулирования формой. Они проще в использовании и подходят для небольших форм.

Пример формы на основе шаблона:

 import { Component } from '@angular/core'; @Component({ selector: 'app-login', template: ` <form (ngSubmit)="onSubmit()"> <input [(ngModel)]="username" name="username" placeholder="Username" required> <input [(ngModel)]="password" name="password" type="password" placeholder="Password" required> <button type="submit">Login</button> </form>
`
})
export class LoginComponent {
username: string;
password: string;

onSubmit() {
console.log('Username:', this.username);
console.log('Password:', this.password);
}
}

HTTP-запросы и взаимодействие с API

Для взаимодействия с серверным API Angular предоставляет HttpClient модуль. Он позволяет выполнять HTTP-запросы и обрабатывать ответы.

Читайте также  YouTube меняет название функции поощрения

Настройка HttpClient

Сначала необходимо импортировать HttpClientModule в главный модуль приложения:

 import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; @NgModule({ imports: [BrowserModule, HttpClientModule], declarations: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } 

Создание сервиса для работы с API

Рекомендуется создавать отдельные сервисы для работы с API. Вот пример сервиса для работы с API пользователей:

 import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserService { private apiUrl = 'https://api.example.com/users'; constructor(private http: HttpClient) { } getUsers(): Observable<any> { return this.http.get(this.apiUrl); } getUser(id: number): Observable<any> { return this.http.get(`${this.apiUrl}/${id}`); } createUser(user: any): Observable<any> { return this.http.post(this.apiUrl, user); } updateUser(id: number, user: any): Observable<any> { return this.http.put(`${this.apiUrl}/${id}`, user); } deleteUser(id: number): Observable<any> { return this.http.delete(`${this.apiUrl}/${id}`); } } 

Использование сервиса в компоненте

Теперь можно использовать созданный сервис в компонентах для выполнения HTTP-запросов:

 import { Component, OnInit } from '@angular/core'; import { UserService } from './user.service'; @Component({ selector: 'app-user-list', template: ` <ul> <li *ngFor="let user of users">{{ user.name }}</li> </ul> ` }) export class UserListComponent implements OnInit { users: any[]; constructor(private userService: UserService) { } ngOnInit() { this.userService.getUsers().subscribe( (data) => { this.users = data; }, (error) => { console.error('Error fetching users:', error); } ); } } 

Аутентификация и авторизация

Реализация аутентификации и авторизации является важной частью многих веб-приложений. В Angular это можно реализовать с помощью сервисов и гвардов (guards).

Сервис аутентификации

Создадим сервис для управления аутентификацией:

 import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AuthService { private currentUserSubject: BehaviorSubject<any>; public currentUser: Observable<any>; constructor(private http: HttpClient) { this.currentUserSubject = new BehaviorSubject<any>(JSON.parse(localStorage.getItem('currentUser'))); this.currentUser = this.currentUserSubject.asObservable(); } public get currentUserValue() { return this.currentUserSubject.value; } login(username: string, password: string) { return this.http.post<any>('https://api.example.com/login', { username, password }) .pipe(map(user => { localStorage.setItem('currentUser', JSON.stringify(user)); this.currentUserSubject.next(user); return user; })); } logout() { localStorage.removeItem('currentUser'); this.currentUserSubject.next(null); } } 

Гвард для защиты маршрутов

Создадим гвард для защиты маршрутов, требующих аутентификации:

 import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { AuthService } from './auth.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor( private router: Router, private authService: AuthService ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { const currentUser = this.authService.currentUserValue; if (currentUser) { return true; } this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); return false; } } 

Применение гварда к маршрутам

Теперь можно применить гвард к защищенным маршрутам в конфигурации маршрутизации:

 import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { LoginComponent } from './login/login.component'; import { ProfileComponent } from './profile/profile.component'; import { AuthGuard } from './auth.guard'; const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'login', component: LoginComponent }, { path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } 

Оптимизация производительности

Оптимизация производительности является важным аспектом разработки Angular-приложений. Рассмотрим несколько техник для улучшения производительности.

Ленивая загрузка модулей

Ленивая загрузка позволяет загружать модули только когда они необходимы, что уменьшает начальный размер загружаемого приложения.

Читайте также  Очистка корзины в Laravel интернет-магазине

Пример настройки ленивой загрузки:

 const routes: Routes = [ { path: '', component: HomeComponent }, { path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) } ]; 

Использование OnPush стратегии обнаружения изменений

Стратегия OnPush позволяет оптимизировать процесс обнаружения изменений в компонентах:

 import { Component, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'app-my-component', template: '...', changeDetection: ChangeDetectionStrategy.OnPush }) export class MyComponent { } 

Использование trackBy в ngFor

Использование trackBy в директиве ngFor может значительно улучшить производительность при работе с большими списками:

 <li *ngFor="let item of items; trackBy: trackByFn">{{ item.name }}</li> trackByFn(index, item) { return item.id; } 

Оптимизация рендеринга

Для оптимизации рендеринга можно использовать такие техники, как:

  • Виртуальная прокрутка для больших списков
  • Использование pure pipes вместо методов в шаблонах
  • Минимизация вложенности компонентов

Тестирование Angular-приложений

Тестирование является неотъемлемой частью разработки надежных приложений. Angular предоставляет инструменты для модульного тестирования и тестирования компонентов.

Модульное тестирование

Для модульного тестирования в Angular используется Jasmine в сочетании с Karma. Вот пример теста для сервиса:

 import { TestBed } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { UserService } from './user.service'; describe('UserService', () => { let service: UserService; let httpMock: HttpTestingController; beforeEach(() => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], providers: [UserService] }); service = TestBed.inject(UserService); httpMock = TestBed.inject(HttpTestingController); }); afterEach(() => { httpMock.verify(); }); it('should retrieve users', () => { const dummyUsers = [ { id: 1, name: 'John' }, { id: 2, name: 'Jane' } ]; service.getUsers().subscribe(users => { expect(users.length).toBe(2); expect(users).toEqual(dummyUsers); }); const req = httpMock.expectOne('https://api.example.com/users'); expect(req.request.method).toBe('GET'); req.flush(dummyUsers); }); }); 

Тестирование компонентов

Для тестирования компонентов можно использовать TestBed и создавать фиктивные (mock) зависимости:

 import { ComponentFixture, TestBed } from '@angular/core/testing'; import { UserListComponent } from './user-list.component'; import { UserService } from './user.service'; import { of } from 'rxjs'; describe('UserListComponent', () => { let component: UserListComponent; let fixture: ComponentFixture<UserListComponent>; let userServiceSpy: jasmine.SpyObj<UserService>; beforeEach(async () => { const spy = jasmine.createSpyObj('UserService', ['getUsers']); await TestBed.configureTestingModule({ declarations: [ UserListComponent ], providers: [ { provide: UserService, useValue: spy } ] }).compileComponents(); userServiceSpy = TestBed.inject(UserService) as jasmine.SpyObj<UserService>; }); beforeEach(() => { fixture = TestBed.createComponent(UserListComponent); component = fixture.componentInstance; }); it('should create', () => { expect(component).toBeTruthy(); }); it('should load users', () => { const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }]; userServiceSpy.getUsers.and.returnValue(of(users)); fixture.detectChanges(); expect(component.users).toEqual(users); }); }); 

Развертывание приложения

После разработки и тестирования приложения следующим шагом является его развертывание. Angular CLI предоставляет инструменты для сборки приложения для производственного использования.

Сборка приложения

Для сборки приложения используется следующая команда:

ng build --prod

Эта команда создаст оптимизированную версию приложения в директории dist/.

Оптимизация сборки

Для дальнейшей оптимизации сборки можно использовать следующие техники:

  • Включение Ahead-of-Time (AOT) компиляции
  • Минификация и обфускация кода
  • Оптимизация изображений
  • Использование сжатия gzip

Развертывание на сервере

После сборки приложения его можно развернуть на веб-сервере. Для этого необходимо:

  1. Скопировать содержимое директории dist/ на сервер
  2. Настроить сервер для обработки маршрутов Angular

Пример конфигурации для Nginx:

 server { listen 80; server_name example.com; root /path/to/dist/folder; index index.html; location / { try_files $uri $uri/ /index.html; } } 

Заключение

В этом учебном материале были рассмотрены основные аспекты создания многостраничных приложений в Angular. Были освещены такие темы, как структура приложения, компоненты, сервисы, маршрутизация, работа с формами и HTTP-запросами, аутентификация, оптимизация производительности, тестирование и развертывание.

Советы по созданию сайтов