首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在重新加载或更改路由时,如何在页面上保持警报框?

在重新加载或更改路由时,如何在页面上保持警报框?
EN

Stack Overflow用户
提问于 2022-07-01 16:59:19
回答 1查看 83关注 0票数 0

我需要在Registration页面上维护一个警告框,显示用户已成功注册。但是,通过重定向到Login表单,此框将消失,因为页面会刷新。

我使用Alert组件来管理这个场景。所有的功能都是完美无缺的,但是这个问题确实让我感到困惑。我分享了我的代码,并希望你帮助我找到这个困境的根源。

alert.component.ts

代码语言:javascript
复制
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Subscription } from 'rxjs';
import { Alert, AlertType } from 'src/app/_models/alert';
import { AlertService } from 'src/app/_services/alert.service';

@Component({ selector: 'alert', 
templateUrl: 'alert.component.html',
styleUrls: ['./alert.component.scss'] })
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);

                setTimeout(() => this.removeAlert(alert), 5000);
           });

        // 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;

        if (this.fade) {
            // fade out alert
            this.alerts.find(x => x === alert).fade = true;

            // remove alert after faded out
            setTimeout(() => {
                this.alerts = this.alerts.filter(x => x !== alert);
            }, 250);
        } else {
            // remove alert
            this.alerts = this.alerts.filter(x => x !== alert);
        }
    }

    cssClass(alert: Alert) {
        if (!alert) return;

        const classes = ['toast'];
                
        const alertTypeClass = {
            [AlertType.Success]: 'toast-success',
            [AlertType.Error]: 'toast-error',
            [AlertType.Info]: 'toast-info',
            [AlertType.Warning]: 'toast-warning'
        }

        classes.push(alertTypeClass[alert.type]);

        if (alert.fade) {
            classes.push('fade');
        }

        return classes.join(' ');
    }
}

alert.service.ts

代码语言:javascript
复制
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { Alert, AlertType } from '../_models/alert';


@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?: any) {
        this.alert(new Alert({ ...options, type: AlertType.Success, message }));
    }

    error(message: string, options?: any) {
        this.alert(new Alert({ ...options, type: AlertType.Error, message }));
    }

    info(message: string, options?: any) {
        this.alert(new Alert({ ...options, type: AlertType.Info, message }));
    }

    warn(message: string, options?: any) {
        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 }));
    }
}

这是一段代码,其中调用了警报消息(应该注意,keepAfterRouteChange被设置为True):

代码语言:javascript
复制
onSubmit() {
    this.submitted = true;

    // reset alerts on submit
    this.alertService.clear();

    // stop here if form is invalid
    if (this.form.invalid) {
      return;
    }

    this.loading = true;
    this.accountService
      .register(this.form.value)
      .pipe(first())
      .subscribe((data) => {
        this.loading = false;
        this.submitted = false;
        if (data.hasError) {
          this.alertService.error(data.errorMessage);
        } else {
          this.alertService.success('Registration successfully completed.', {
            keepAfterRouteChange: true,
          });
          localStorage.setItem('regCount',JSON.parse(localStorage.getItem('regCount')) + 1);
          this.router.navigate(['/login']).then(() => {
            window.location.reload();
          });
        }
      },
      () => {
        this.loading = false;
        this.submitted = false;
        this.alertService.error('Something went wrong.');
      });
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-02 07:44:41

当窗口重新加载时,您的问题可能来自window.location.reload();,所有组件和服务都被刷新。找到其他方法来清除服务,如果这正是这一行的要点。或者寻找其他方法来存储警报应该显示的信息(例如,在SessionStorage或LocalStorage中存储需要显示信息和持续时间的信息)--这似乎不是一个好主意。通常,我们希望避免重新加载窗口--出于同样的原因,丢失所有数据并迫使客户端重新加载所有资源。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72832512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档