import { Injectable, ComponentRef, ComponentFactoryResolver, Injector, ApplicationRef } from '@angular/core'; import { Subject, Observable } from 'rxjs'; import { NotifyEvent, NotifyOptions, NotifyConfig, NotifyData } from './notifiy.options'; import { NotifyContainerComponent } from './notify-container.component'; import { LocaleService } from '@farris/ui-locale'; /** * Check and return true if an object is type of string * @param obj Analyse has to object the string type * @return result of analysis */ export function isString(obj: any): boolean { return typeof obj === 'string'; } /** * Check and return true if an object is type of number * @param obj Analyse has to object the boolean type * @return result of analysis */ export function isNumber(obj: any): boolean { return typeof obj === 'number'; } /** * Check and return true if an object is type of Function * @param obj Analyse has to object the function type * @return result of analysis */ export function isFunction(obj: any): boolean { return typeof obj === 'function'; } @Injectable() export class NotifyService { static THEMES: Array = ['default', 'material', 'bootstrap']; // Init the counter uniqueCounter = 0; private eventSource: Subject = new Subject(); events: Observable = this.eventSource.asObservable(); notifyContainer: ComponentRef; config = new NotifyConfig(); localeService: LocaleService; constructor(private cfr: ComponentFactoryResolver, private injector: Injector, private appRef: ApplicationRef) { this.localeService = this.injector.get(LocaleService); } default(options: NotifyOptions|string|number): void { this.show(options, 'default'); } info(options: NotifyOptions|string|number): void { this.show(options, 'info'); } success(options: NotifyOptions|string|number): void { this.show(options, 'success'); } warning(options: NotifyOptions|string|number): void { this.show(options, 'warning'); } error(options: NotifyOptions|string|number): void { this.show(options, 'danger'); } clearAll() { // this.eventSource.next(new NotifyEvent(NotifyEventType.CLEAR_ALL)); if(this.notifyContainer){ this.notifyContainer.instance.clearAll(); } } clear(id: number) { // this.eventSource.next(new NotifyEvent(NotifyEventType.CLEAR, id)); this.notifyContainer.instance.clear(id); } private createContainer() { if (!this.notifyContainer) { const containerFac = this.cfr.resolveComponentFactory(NotifyContainerComponent); const cmpRef = containerFac.create(this.injector); // cmpRef.instance.id = 'Farris-Notify-Container'; this.appRef.attachView(cmpRef.hostView); document.querySelector('body').appendChild(cmpRef.location.nativeElement); this.notifyContainer = cmpRef; } } private show(options: NotifyOptions | string | number, type: string) { this.createContainer(); let notifyOptions: NotifyOptions; if (isString(options) && options !== '' || isNumber(options)) { notifyOptions = { // 20191129 去除默认标题 // title: this.localeService.getValue('notify.title'), msg: options.toString() } as NotifyOptions; } else { notifyOptions = options as NotifyOptions; } if (!notifyOptions || !notifyOptions.msg) { throw new Error('Farris-Notify: No notify title or message specified!'); } type = type || 'default'; this.uniqueCounter++; const showClose = this._checkConfigItem(this.config, notifyOptions, 'showClose'); let theme: string; if (notifyOptions.theme) { theme = NotifyService.THEMES.indexOf(notifyOptions.theme) > -1 ? notifyOptions.theme : this.config.theme; } else { theme = this.config.theme; } // 判断success类型 展示时间为1.5s if (type === 'success') { if (!notifyOptions.hasOwnProperty('timeout')) { notifyOptions.timeout = 1500; } } const newNotifyOpts: NotifyData = { id: notifyOptions.id?notifyOptions.id:this.uniqueCounter, title: notifyOptions.title, msg: notifyOptions.msg, showClose, type: 'toasty-type-' + type, theme: 'toasty-theme-' + theme, onAdd : notifyOptions.onAdd && isFunction(notifyOptions.onAdd) ? notifyOptions.onAdd : null, onRemove : notifyOptions.onRemove && isFunction(notifyOptions.onRemove) ? notifyOptions.onRemove : null, buttons:notifyOptions.buttons?notifyOptions.buttons:null }; newNotifyOpts.timeout = notifyOptions.hasOwnProperty('timeout') ? notifyOptions.timeout : this.config.timeout; // this.eventSource.next(new NotifyEvent(NotifyEventType.ADD, newNotifyOpts)); this.notifyContainer.instance.config = this.config; this.notifyContainer.instance.position = this.config.position; this.notifyContainer.instance.add(newNotifyOpts); (this.notifyContainer.instance as NotifyContainerComponent).empty.subscribe(() => { this.clearDom(); }); this.notifyContainer.changeDetectorRef.markForCheck(); this.notifyContainer.changeDetectorRef.detectChanges(); if (notifyOptions.onAdd && isFunction(notifyOptions.onAdd)) { notifyOptions.onAdd.call(this, newNotifyOpts); } } private _checkConfigItem(config: any, options: any, property: string) { if (options[property] === false) { return false; } else if (!options[property]) { return config[property]; } else { return true; } } private clearDom() { if (this.notifyContainer) { const el = this.notifyContainer.location.nativeElement; if (el.parentNode) { el.parentNode.removeChild(el); } this.notifyContainer.destroy(); this.notifyContainer = undefined; } } } // export function notifyServiceFactory(config: NotifyConfig): NotifyService { // return new NotifyService(config, ); // }