【问题标题】:Proper way to handle toast notifications in Ionic app在 Ionic 应用程序中处理 toast 通知的正确方法
【发布时间】:2018-01-17 04:51:27
【问题描述】:

我有一个 Ionic 2 应用程序,它在各个地方都有吐司通知。

一个很好的例子是用户在应用程序上更新他们的个人资料,然后我运行一些验证检查。如果用户未通过某些验证,我可能会调用以下代码:

      let toast = this.toastCtrl.create({
        message: 'Sorry, your password must be at least 6 characters long.  Your account was not updated.',
        duration: 3000,
        position: 'top'
      });
      toast.present();

那里没有问题。它只显示 3 秒然后消失。

同时显示多个时会出现问题。例如,用户可能输入了一个 6 个字符的密码,但由于其他原因它没有验证,因此会引发另一个 toast 通知:

    let toast = this.toastCtrl.create({
      message: 'Sorry, your passwords do not match.  Your account was not updated.',
      duration: 3000,
      position: 'top'
    });
    toast.present();

这会导致 2 个 toast 重叠,一个将永久保留。这两个重叠不是问题,但一个无限期保留的事实是一个大问题。

我想这是因为我每次都有效地覆盖了 toast 变量。

解决此问题的最佳方法是什么?我不想拥有toast1toast2 等,因为这不会解决问题,因为用户可能会两次启动相同的 toast 通知(

【问题讨论】:

  • 如何制作吐司?我同时创建了多个 toast,并且都按预期工作。
  • 很多let toast = this.toastCtrl.create({ ... }); toast.present();。我只在实验室 (ionic serve --lab) 上测试过,但假设它在设备上是一样的。
  • 请查看this answer。通过对所有 toast 使用相同的属性,您每次可以只显示一个 toast(因为如果它们是验证消息,重叠 toast 是没有意义的)。
  • @sebaferreras:你知道如何重现这个问题吗?我尝试了很多方法,但无法面对它。哈哈

标签: ionic-framework ionic2 toast


【解决方案1】:

我建议处理服务中的所有Toast 交互。并将其注入您需要的任何组件/页面/服务中。在服务中,您保留对单个Toast 的引用,并在呈现之前调用dismiss()。 此解决方案可防止您一次呈现多个 Toast。

ToastService:

import { Injectable } from '@angular/core';
import { ToastController, Toast } from 'ionic-angular';

@Injectable()
export class ToastService{
    toast: Toast = null;

    constructor(private toastCtrl: ToastController){ }

    presentToast(text:string):void{
        let toastData = {
            message: text,
            duration: 3000,
            position: 'top'
        }

        this.showToast(toastData);
    }

    presentClosableToast(text:string):void{
        let toastData = {
            message: text,
            showCloseButton: true,
            closeButtonText: 'X',
            position: 'top' 
        };

        this.showToast(toastData);
    }

    private showToast(data:any):void{
        this.toast ? this.toast.dismiss() : false;
        this.toast = this.toastCtrl.create(data);
        this.toast.present();
    }
}

【讨论】:

  • 我必须说我不确定这是否是一个好方法,因为提供程序并不意味着用于直接与最终用户(或 UI)交互。更好的方法是使用该代码创建一个BaseComponent,并用它扩展您的页面。或者,如果您仅在单个页面中使用 toast,请将此代码添加到该页面。
  • 我同意@sebaferreras。在这种情况下,扩展 classcomponent 有区别吗?我昨天做了一个编辑(见编辑历史),我扩展了class。我使用了class,因为只需要功能而不需要模板。
  • 主要区别在于组件也有元数据(装饰器),即使是硬元数据在这个例子中并不重要,它可能会在构建生产时导致一些错误(它只发生在某些版本的 Ionic) 中,所以你可以添加一个 empty decorator 来避免这种情况。请查看this SO answer,我在其中创建了一个BaseComponent 来处理显示/创建toast :)
【解决方案2】:

你可以这样做。

当你需要举杯时。作为函数调用。 函数内部。你有一个 3 秒的计时器。 那么如果再次调用吐司功能。你需要清除计时器然后 重新设置它。喜欢这段代码。

//delacare timer
_timer:any = null;

showToast(){
    let toast:any;
    //check if timer is running ,if its clear out and dismiss existing toast  
    if (this._timer) { 
         toast.dismiss()
         clearTimeout(this._timer)
    };

    this._timer = setTimeout(() => {
       toast = this.toastCtrl.create({
        message: 'Sorry, your passwords do not match.  Your account was not updated.', 
       position: 'top'
    });
    toast.present();
    },3000)

}

更新

或者你也可以像这样放置一个字符串参数。避免许多 toast 代码。

showToast(string_message){
        let toast:any;
        //check if timer is running it its . clear out  
        if (this._timer) { 
             toast.dismiss()
             clearTimeout(this._timer)
        };

        this._timer = setTimeout(() => {
           toast = this.toastCtrl.create({
            message: string_message, 
           position: 'top'
        });
        toast.present();
        },3000)

    }

【讨论】:

    猜你喜欢
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多