ionic3自带的ToastController创建的toast比较简单,不支持图标,且点击toast时是没有事件回调的……
这个时候,如果想扩展这些功能,一是修改源码,二是自己实现,然而这两种方法都比较麻烦,比较好的解决方案是利用现有的开源代码,搜索ionic的相关组件寥寥无几,这个时候转换下思路,搜索angular的相关组件会发现有几个,经过比较后觉得ngx-toastr较为适合。它提供了在线Demo.
image.png
ionic3集成使用ngx-toastr
根据Github上的文档说明,进行如下步骤:
- 安装组件
npm install ngx-toastr --save
代码语言:javascript复制npm install @angular/animations --save
- 添加样式
Github文档是通过修改
angular-cli.json
文件来导入样式的,而对于ionic来说,该类似文件封装在源码里面,不应该修改,所以改为在index.html里面引入样式,如:
<link href="assets/libs/ngx-toastr/toastr.min.css" rel="stylesheet">
- 添加ToastrModule到app.module.ts
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‘
此方式;
- 使用 上面步骤处理好后,就可以很方便使用了:
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
未定义的错误。
处理这个有两种方式:
- 清空或者删除toastr-bs4-alert.scss文件。
- 无论想不想用bootstrap,在调用toastr-bs4-alert.scss前,先类似导入如下两个模块,它说导入完编译后就会没有了,见截图说明(我不明白为啥导入后反而没有,黑人问号脸):
@import "~bootstrap/scss/functions"; @import "~bootstrap/scss/variables";
image.png