Angular 14 - Предупреждения (Toaster) Учебное пособие и пример
В этом руководстве мы рассмотрим, как реализовать alert/toaster уведомления сообщений в Angular 14.
Уведомления о предупреждениях (alert) являются распространенным требованием в веб-приложениях для отображения сообщений о состоянии пользователю (например, сообщения об ошибке, успехе, предупреждении и информационных оповещениях).
Пример Angular 14 Alerts App
Пример приложения реализует оповещения в пользовательском модуле Angular alert и содержит следующие две страницы, демонстрирующие, как работают оповещения:
- Single Alert (
HomeComponent
) - содержит кнопки для отправки оповещений компоненту<alert>
по умолчанию, расположенному в шаблоне компонента корневого приложения (/src/app/app.component.html
). Это также позволяет переключать параметры оповещения с помощью флажков. - Multiple Alerts (
MultiAlertsComponent
) - показывает, как на одной странице можно использовать несколько компонентов<alert>
, присвоив каждому из них уникальныйid
и указав, на какой идентификатор следует ориентироваться при отправке сообщения с предупреждением.
Стилизовано с помощью Bootstrap 5
Пример оформлен с использованием CSS из Bootstrap 5.2. Если вы не используете Bootstrap, вы можете изменить классы CSS для компонентов оповещения в методе cssClass()
компонента оповещения (/src/_alert/alert.component.ts
) и обновить HTML в шаблоне компонента оповещения (/src/_alert/alert.component.html
).
Код на GitHub
Код проекта доступен на GitHub по адресу. Вот оно в действии:
Запуск локального примера уведомлений о предупреждениях Angular 14
Для начала работы нам необходимо выполнить некоторые шаги:
- Установить Node.js и npm от https://nodejs.org.
- Загрузить или клонировать исходный код учебного проекта с https://github.com/cornflourblue/angular-14-alert-notifications.
- Установить все необходимые пакеты npm, запустив
npm install
илиnpm i
из командной строки в корневой папке проекта (где находится package.json). - Запустить приложение, запустив
npm start
из командной строки в корневой папке проекта, это создаст приложение и автоматически запустит его в браузере по URLhttp://localhost:4200
.
ПРИМЕЧАНИЕ. Вы также можете запустить приложение с помощью команды Angular CLIng serve --open
. Для этого сначала установите Angular CLI globally в вашей системе с помощью командыnpm install -g @angular/cli
.
Добавляем Alert в приложение Angular 14
Чтобы добавить оповещения (alert) в ваше приложение Angular, скопируйте папку /src/app/_alert
из примера проекта в свой проект, папка содержит следующий модуль оповещения и связанные с ним файлы:
alert.component.html
- шаблон компонента оповещений, содержащий html-код для отображения оповещений.alert.component.ts
- компонент оповещения с логикой отображения оповещений.alert.model.ts
- класс модели оповещений, который определяет свойства оповещения, также включает в себя перечислениеAlertType
, определяющее различные типы оповещений.alert.module.ts
- модуль оповещения, который инкапсулирует компонент оповещения, чтобы он мог быть импортирован модулем приложения.alert.service.ts
- служба оповещений, которая может использоваться любым компонентом или службой angular для отправки оповещений компонентам оповещения.index.ts
- файл barrel, который повторно экспортирует модуль оповещения, службу и модель, чтобы их можно было импортировать, используя только путь к папке вместо полного пути к каждому файлу, а также позволяет импортировать из нескольких файлов с помощью одного импорта.
Импорт Alert Module в App Module
Чтобы сделать компонент оповещения доступным для вашего приложения Angular 14, вам необходимо добавить AlertModule
в массив imports
вашего модуля приложения (app.module.ts
). Смотрите модуль приложения из примера приложения ниже, модуль оповещения (alert module) импортируется в строке 5
и добавляется в массив импорта модуля приложения в строке 16
.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AlertModule } from './_alert';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home';
import { MultiAlertsComponent } from './multi-alerts';
@NgModule({
imports: [
BrowserModule,
FormsModule,
AlertModule,
AppRoutingModule
],
declarations: [
AppComponent,
HomeComponent,
MultiAlertsComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
Теги alert и /alert для отображения оповещений
Добавьте тег компонента оповещения (<alert>
,</alert>
), где вы хотите, чтобы отображались предупреждающие сообщения. Если на странице есть только один компонент оповещения, вам не нужно указывать id
(идентификатор по умолчанию - "default-alert"
). Любые дополнительные компоненты оповещения должны иметь уникальный идентификатор, указанный с помощью опции ниже.
Атрибуты компонента Alert
Компонент оповещения принимает следующие необязательные атрибуты:
id
- используется, если вы хотите отобразить несколько оповещений в разных местах на одной странице (см. страницу с Multiple Alerts в примере выше). Компонент оповещения с атрибутомid
будет отображать сообщения, отправленные через службу оповещения с соответствующимid
, напримерalertService.error('something broke!', { id: 'alert-1' });
отправит сообщение об ошибке компоненту оповещения сid="alert-1"
. Значение по умолчанию -"default-alert"
.fade
- контролирует, исчезают ли предупреждающие сообщения при закрытии. Значение по умолчанию -true
.
Компонент Global Default Alert
Пример приложения определяет глобальный компонент оповещения (Global Default Alert) по умолчанию в шаблоне компонента корневого приложения (/src/app/app.component.html
). Компонент <alert>
не имеет id
, поэтому сообщения, отправленные в службу оповещений без id
(например, alertService.success('test angular 14 alert!');
), будут отображаться глобальным оповещением по умолчанию.
<!-- main app container -->
<div class="card text-bg-light mx-3">
<div class="card-body text-center">
<alert></alert>
<router-outlet></router-outlet>
</div>
</div>
Отправка оповещений с помощью Alert Service
Теперь, когда вы добавили модуль оповещения и компонент оповещения в свое приложение Angular, вы можете отправлять уведомления о предупреждениях из любого компонента, внедрив службу оповещения (alert service) и вызвав один из ее методов (success()
, error()
, info()
, warn()
).
Параметры alert method
Каждый метод оповещения (alert method) принимает параметры (message: string, options?: AlertOptions)
:
- Первый параметр - это
string
для предупреждающего сообщения, которая может быть обычным текстом или HTML. - Второй параметр - это необязательный объект
AlertOptions
, который поддерживает следующие свойства (все необязательные):
id
- id компонента<alert>
, который будет отображать уведомление о предупреждении. Значение по умолчанию -"default-alert"
.autoClose
- если значениеtrue
, оповещение автоматически закроется через три секунды. Значение по умолчанию равноfalse
.- keepAfterRouteChange - если значение
true
, предупреждение будет продолжать отображаться после одного изменения маршрута, что полезно для отображения предупреждения после автоматического перенаправления (например, после заполнения формы). Значение по умолчанию равноfalse
.
Пример Home Component
Home component из примера приложения вводит alertService
в свой constructor()
, чтобы к ней можно было получить доступ в шаблоне home component для отправки оповещения при нажатии кнопки. В реальном приложении оповещения могут быть вызваны любым типом события, например предупреждением об ошибке при сбое http-запроса или предупреждением об успешном завершении после отправки формы.
Свойство options
содержит параметры оповещения, которые привязаны к флажкам в шаблоне главного компонента.
import { Component } from '@angular/core';
import { AlertService } from '../_alert';
@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
options = {
autoClose: false,
keepAfterRouteChange: false
};
constructor(public alertService: AlertService) { }
}
Пример Home Component Template
Шаблон компонента home (home component template) содержит кнопки для отправки различных оповещений компоненту оповещения по умолчанию и пару флажков для переключения параметров оповещения.
<h1>Angular 14 Alerts</h1>
<div class="my-4">
<button class="btn btn-success m-1" (click)="alertService.success('Success!!', options)">Success</button>
<button class="btn btn-danger m-1" (click)="alertService.error('Error :(', options)">Error</button>
<button class="btn btn-info m-1" (click)="alertService.info('Some info....', options)">Info</button>
<button class="btn btn-warning m-1" (click)="alertService.warn('Warning: ...', options)">Warn</button>
<button class="btn btn-outline-dark m-1" (click)="alertService.clear()">Clear</button>
</div>
<h5>Alert Options</h5>
<div class="form-check mb-2">
<div class="form-check-inline">
<input type="checkbox" name="autoClose" id="autoClose" class="form-check-input" [(ngModel)]="options.autoClose">
<label for="autoClose" class="form-check-label">Auto close alert after three seconds</label>
</div>
</div>
<div class="form-check">
<div class="form-check-inline">
<input type="checkbox" name="keepAfterRouteChange" id="keepAfterRouteChange" class="form-check-input" [(ngModel)]="options.keepAfterRouteChange">
<label for="keepAfterRouteChange">Display alert after one route change</label>
</div>
</div>
Внутри Alert Module Angular 14
Ниже приведена разбивка фрагментов кода, используемых для реализации примера оповещений в Angular 14, вам не нужно знать все подробности о том, как это работает, чтобы использовать модуль оповещений в вашем проекте, это только в том случае, если вы заинтересованы в гайках и болтах или хотите изменить код или поведение.
Alert Service
Путь: /src/app/_alert/alert.service.ts
Alert service действует как связующее звено между любым компонентом в приложении Angular и компонентом alert, который фактически отображает сообщения alert/toaster. Он содержит методы отправки, очистки и подписки на предупреждающие сообщения.
Служба использует классы RxJS Observable и Subject для обеспечения связи с другими компонентами.
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { Alert, AlertType, AlertOptions } from './alert.model';
@Injectable({ providedIn: 'root' })
export class AlertService {
private subject = new Subject<Alert>();
private defaultId = 'default-alert';
// enable subscribing to alerts observable
onAlert(id = this.defaultId): Observable<Alert> {
return this.subject.asObservable().pipe(filter(x => x && x.id === id));
}
// convenience methods
success(message: string, options?: AlertOptions) {
this.alert(new Alert({ ...options, type: AlertType.Success, message }));
}
error(message: string, options?: AlertOptions) {
this.alert(new Alert({ ...options, type: AlertType.Error, message }));
}
info(message: string, options?: AlertOptions) {
this.alert(new Alert({ ...options, type: AlertType.Info, message }));
}
warn(message: string, options?: AlertOptions) {
this.alert(new Alert({ ...options, type: AlertType.Warning, message }));
}
// main alert method
alert(alert: Alert) {
alert.id = alert.id || this.defaultId;
this.subject.next(alert);
}
// clear alerts
clear(id = this.defaultId) {
this.subject.next(new Alert({ id }));
}
}
Alert Component
Путь: /src/app/_alert/alert.component.ts
Компонент alert управляет добавлением и удалением оповещений в пользовательском интерфейсе, он поддерживает массив оповещений, которые отображаются шаблоном компонента.
Метод ngOnInit
подписывается на наблюдаемый объект, возвращаемый из alertService.onAlert()
позволяет компоненту оповещения получать уведомления всякий раз, когда в службу оповещения отправляется сообщение с предупреждением, и добавлять его в массив alerts
для отображения. Отправка оповещения с пустым сообщением в службу оповещений указывает компоненту оповещения очистить массив оповещений. Этот метод также вызывает router.events.subscribe()
для подписки на события изменения маршрута, чтобы автоматически удалять предупреждения об изменениях маршрута.
Метод ngOnDestroy()
отменяет подписку на службу оповещений и маршрутизатор при уничтожении компонента, чтобы предотвратить утечку памяти из-за потерянных подписок.
Метод removeAlert()
удаляет указанный объект alert
из массива, он позволяет закрывать отдельные оповещения в пользовательском интерфейсе.
Метод cssClass()
возвращает соответствующий класс bootstrap alert для каждого из типов оповещений, если вы используете что-то отличное от bootstrap, вы можете изменить возвращаемые классы CSS в соответствии с вашим приложением.
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs';
import { Alert, AlertType } from './alert.model';
import { AlertService } from './alert.service';
@Component({ selector: 'alert', templateUrl: 'alert.component.html' })
export class AlertComponent implements OnInit, OnDestroy {
@Input() id = 'default-alert';
@Input() fade = true;
alerts: Alert[] = [];
alertSubscription!: Subscription;
routeSubscription!: Subscription;
constructor(private router: Router, private alertService: AlertService) { }
ngOnInit() {
// subscribe to new alert notifications
this.alertSubscription = this.alertService.onAlert(this.id)
.subscribe(alert => {
// clear alerts when an empty alert is received
if (!alert.message) {
// filter out alerts without 'keepAfterRouteChange' flag
this.alerts = this.alerts.filter(x => x.keepAfterRouteChange);
// remove 'keepAfterRouteChange' flag on the rest
this.alerts.forEach(x => delete x.keepAfterRouteChange);
return;
}
// add alert to array
this.alerts.push(alert);
// auto close alert if required
if (alert.autoClose) {
setTimeout(() => this.removeAlert(alert), 3000);
}
});
// clear alerts on location change
this.routeSubscription = this.router.events.subscribe(event => {
if (event instanceof NavigationStart) {
this.alertService.clear(this.id);
}
});
}
ngOnDestroy() {
// unsubscribe to avoid memory leaks
this.alertSubscription.unsubscribe();
this.routeSubscription.unsubscribe();
}
removeAlert(alert: Alert) {
// check if already removed to prevent error on auto close
if (!this.alerts.includes(alert)) return;
// fade out alert if this.fade === true
const timeout = this.fade ? 250 : 0;
alert.fade = this.fade;
setTimeout(() => {
// filter alert out of array
this.alerts = this.alerts.filter(x => x !== alert);
}, timeout);
}
cssClass(alert: Alert) {
if (!alert) return;
const classes = ['alert', 'alert-dismissible'];
const alertTypeClass = {
[AlertType.Success]: 'alert-success',
[AlertType.Error]: 'alert-danger',
[AlertType.Info]: 'alert-info',
[AlertType.Warning]: 'alert-warning'
}
if (alert.type !== undefined) {
classes.push(alertTypeClass[alert.type]);
}
if (alert.fade) {
classes.push('fade');
}
return classes.join(' ');
}
}
Alert Component Template
Путь: /src/app/_alert/alert.component.html
Шаблон компонента alert отображает предупреждающее сообщение для каждого предупреждения в массиве alerts, используя директиву Angular *ngFor
.
Bootstrap 5.2 используется для оформления alerts/toaster уведомлений в примере, вы можете изменить классы HTML и CSS в этом шаблоне в соответствии с вашим приложением, если вы не используете Bootstrap.
<div *ngFor="let alert of alerts" class="{{cssClass(alert)}}">
<div [innerHTML]="alert.message"></div>
<button type="button" class="btn-close" (click)="removeAlert(alert)"></button>
</div>
Alert Models
Путь: /src/app/_alert/alert.model.ts
Файл модели оповещения содержит модели Alert
, AlertType
и AlertOptions
.
Alert
определяет свойства каждого объекта оповещения.AlertType
это перечисление, содержащее типы оповещений.AlertOptions
определяет параметры, доступные при отправке оповещения в службу оповещений.
export class Alert {
id?: string;
type?: AlertType;
message?: string;
autoClose?: boolean;
keepAfterRouteChange?: boolean;
fade?: boolean;
constructor(init?:Partial<Alert>) {
Object.assign(this, init);
}
}
export enum AlertType {
Success,
Error,
Info,
Warning
}
export class AlertOptions {
id?: string;
autoClose?: boolean;
keepAfterRouteChange?: boolean;
}
Angular Alert Module
Путь: /src/app/_alert/alert.module.ts
AlertModule
инкапсулирует компонент оповещения, чтобы его можно было импортировать и использовать другими модулями Angular.
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AlertComponent } from './alert.component';
@NgModule({
imports: [CommonModule],
declarations: [AlertComponent],
exports: [AlertComponent]
})
export class AlertModule { }