DevGang
Авторизоваться

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 по адресу. Вот оно в действии:

Запуск локального примера уведомлений о предупреждениях&nbsp;Angular 14

Для начала работы нам необходимо выполнить некоторые шаги:

  1. Установить Node.js и npm от https://nodejs.org.
  2. Загрузить или клонировать исходный код учебного проекта с https://github.com/cornflourblue/angular-14-alert-notifications.
  3. Установить все необходимые пакеты npm, запустив npm install или npm i из командной строки в корневой папке проекта (где находится package.json).
  4. Запустить приложение, запустив npm start из командной строки в корневой папке проекта, это создаст приложение и автоматически запустит его в браузере по URL http://localhost:4200.
ПРИМЕЧАНИЕ. Вы также можете запустить приложение с помощью команды Angular CLI ng 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>

Отправка оповещений с помощью&nbsp;Alert Service

Теперь, когда вы добавили модуль оповещения и компонент оповещения в свое приложение Angular, вы можете отправлять уведомления о предупреждениях из любого компонента, внедрив службу оповещения (alert service) и вызвав один из ее методов (success(), error(), info(), warn()).

Параметры alert method

Каждый метод оповещения (alert method) принимает параметры (message: string, options?: AlertOptions):

  1. Первый параметр - это string для предупреждающего сообщения, которая может быть обычным текстом или HTML.
  2. Второй параметр - это необязательный объект 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&nbsp;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 { }
#Angular
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В подарок 100$ на счет при регистрации

Получить