ionic3使用带图标带事件的toast

2018-08-20 10:51:42 浏览数 (1)

ionic3自带的ToastController创建的toast比较简单,不支持图标,且点击toast时是没有事件回调的……

这个时候,如果想扩展这些功能,一是修改源码,二是自己实现,然而这两种方法都比较麻烦,比较好的解决方案是利用现有的开源代码,搜索ionic的相关组件寥寥无几,这个时候转换下思路,搜索angular的相关组件会发现有几个,经过比较后觉得ngx-toastr较为适合。它提供了在线Demo.

image.png

ionic3集成使用ngx-toastr

根据Github上的文档说明,进行如下步骤:

  1. 安装组件
代码语言:javascript复制
npm install ngx-toastr --save
代码语言:javascript复制
npm install @angular/animations --save
  1. 添加样式 Github文档是通过修改angular-cli.json文件来导入样式的,而对于ionic来说,该类似文件封装在源码里面,不应该修改,所以改为在index.html里面引入样式,如:
代码语言:javascript复制
  <link href="assets/libs/ngx-toastr/toastr.min.css" rel="stylesheet">
  1. 添加ToastrModule到app.module.ts
代码语言:javascript复制
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrModule } from 'ngx-toastr';

@NgModule({
  imports: [
    BrowserAnimationsModule, // required animations module
    ToastrModule.forRoot(), // ToastrModule added
  ]
})
export class AppModule {}

其中除了ToastrModule,BrowserAnimationsModule也是需要导入的,它其实对应着第一步安装的@angular/animations,动画的导入早期也是import * from ‘@angular/animations‘,只是后期把animations抽离后就变成了import * from '@angular/platform-browser/animations‘此方式;

  1. 使用 上面步骤处理好后,就可以很方便使用了:
代码语言:javascript复制
import { ToastrService } from 'ngx-toastr';
@Component({
  ...
})
export class YourComponent {
  constructor(private toastr: ToastrService) {}

  showSuccess() {
    this.toastr.success('Hello world!', 'Toastr fun!');
  }
}

防止污染ionic自带的toast样式

ngx-toastr的样式刚好和ionic都用到了.toast-container的class,所以会影响,此时,把toastr.min.css中的.toast-container 替换为.overlay-container .toast-container即可。

ngx-toastr把toasts放进自定义容器

默认toasts全局显示,如果想限定在某个div或容器里面,使得该容器不可见时不让toast干扰到其它标签,就可以利用ToastContainerModule来实现。 配置:

代码语言:javascript复制
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { ToastrModule, ToastContainerModule } from 'ngx-toastr';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,

    ToastrModule.forRoot({ positionClass: 'inline' }),
    ToastContainerModule,
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

调用:

代码语言:javascript复制
import { Component, OnInit, ViewChild } from '@angular/core';

import { ToastContainerDirective, ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-root',
  template: `
  <h1><a (click)="onClick()">Click</a></h1>
  <div toastContainer></div>
`,
})
export class AppComponent implements OnInit {
  @ViewChild(ToastContainerDirective) toastContainer: ToastContainerDirective;

  constructor(private toastrService: ToastrService) {}
  ngOnInit() {
    this.toastrService.overlayContainer = this.toastContainer;
  }
  onClick() {
    this.toastrService.success('in div');
  }
}

注意:我不想在手机上用bootstrap,所以没导入它bootstrap相关样式,但是在打--prod编译时,还是会检测toastr-bs4-alert.scss里面的样式,爆出: @include border-radius($alert-border-radius);中$alert-border-radius未定义的错误。

处理这个有两种方式:

  1. 清空或者删除toastr-bs4-alert.scss文件。
  2. 无论想不想用bootstrap,在调用toastr-bs4-alert.scss前,先类似导入如下两个模块,它说导入完编译后就会没有了,见截图说明(我不明白为啥导入后反而没有,黑人问号脸):

@import "~bootstrap/scss/functions"; @import "~bootstrap/scss/variables";

image.png

0 人点赞