import { Component, ComponentFactoryResolver, Renderer, ViewChild, ViewContainerRef } from '@angular/core'; import { BlockerDelegate,ViewController,NavParams,NavOptions,GestureController,GESTURE_MENU_SWIPE,GESTURE_GO_BACK_SWIPE,Config} from 'ionic-angular' import { ModalPopIn, ModalPopOut } from '../transition' import { BaseLog as Log } from 'base-log'; const log = new Log('ModalComponent'); @Component({ selector: 'modal', template:` ` }) export class ModalComponent { @ViewChild('viewport', { read: ViewContainerRef }) _viewport: ViewContainerRef; _bdDismiss: boolean; _enabled: boolean; _gestureBlocker: BlockerDelegate; instance _showBackdrop constructor( public _cfr: ComponentFactoryResolver, public _renderer: Renderer, public _navParams: NavParams, public _viewCtrl: ViewController, gestureCtrl: GestureController, config: Config ) { config.setTransition('modal-pop-in',ModalPopIn); // 导入弹入动画 config.setTransition('modal-pop-out',ModalPopOut);// 导入弹出动画 let opts = _navParams.get('opts') || {}; this._gestureBlocker = gestureCtrl.createBlocker({ disable: [GESTURE_MENU_SWIPE, GESTURE_GO_BACK_SWIPE] // 后退和菜单禁止手势 }); this._bdDismiss = opts.enableBackdropDismiss; log.info('_bdDismiss',this._bdDismiss); this._showBackdrop = opts.showBackdrop; } // == 预加载 ionViewPreLoad() { this._load(this._navParams.data.component); } // == 加载子组件 _load(component: any) { if (component) { // == 创建dom const componentFactory = this._cfr.resolveComponentFactory(component); const componentRef = this._viewport.createComponent(componentFactory, this._viewport.length, this._viewport.parentInjector, []); this._viewCtrl._setInstance(componentRef.instance); this.instance = componentRef.instance; this._enabled = true;// dom创建后才开放dismiss等事件 this._viewCtrl.willEnter.subscribe(this._viewWillEnter.bind(this)); this._viewCtrl.didLeave.subscribe(this._viewDidLeave.bind(this)); this._addComponentEvents(); } } _viewWillEnter = () => { this._gestureBlocker.block(); } // 添加组件事件 _addComponentEvents = () => { // 点击确定按钮事件 if(this.instance.okEvent){ this.instance.okEvent.subscribe((data) =>{ this._dismiss(data, 'button'); }); } // 点击取消按钮事件 if(this.instance.cancelEvent){ this.instance.cancelEvent.subscribe((data) =>{ this._dismiss(data, 'button'); }); } // 单纯关闭弹窗事件 if(this.instance.closeEvent){ this.instance.closeEvent.subscribe(() =>{ this._viewCtrl.dismiss().catch(() => {}); // 自动触发关闭当前组件 }); } } _viewDidLeave() { this._gestureBlocker.unblock(); } // 背景点击 _bdClick() { log.info('_bdDismiss',this._bdDismiss); if(!this._bdDismiss) return; this._dismiss(null, 'backdrop'); } // == 关闭弹窗 _dismiss = (data,type?) => { if(!this._enabled) return; const option = this._navParams.data; const opts: NavOptions = { minClickBlockDuration: 400 }; if(option.autoDismiss){ // 自动触发关闭当前组件 this._viewCtrl.dismiss(null, type, opts).catch(() => {}); } if(option.success) option.success(data, this._viewCtrl, type, this.instance); } ngOnDestroy() { if(this._gestureBlocker.blocked === false) log.info('gesture blocker must be already unblocked'); this._gestureBlocker.destroy(); } }