nimble-ui
Version:
296 lines (293 loc) • 9.4 kB
JavaScript
import { getBackData, callFn } from 'nimble-lib';
import { POPUP_EVENT } from '../../_commons/constant';
import {POPUP_DEFAULT_CONFIG} from './constant';
import Service from '../services';
import {PopupCore} from './Popup.core';
/**
* popup的公共方法
*
* @export
* @class PopupCommon
*/
export class PopupBase extends Service {
name = 'PopupBase';
defaultOption = POPUP_DEFAULT_CONFIG;
_cache = {}; // 打开的popup
constructor(Vue, options) {
super(options);
this.setDefaultOptions(options);
this._setSPopup(Vue);
}
/**
* 监听事件
* @param {*} popup popup组件
* @param {*} options 选项
* @param {*} closeCb 关闭的回调
* @returns {Promise}
*/
_initWatch(popup, options, closeCb) {
let _that = this;
return new Promise((resolve, reject) => {
let timeout = null;
if (!popup) {
return reject(new Error('popup 不能为空'));
}
let eventMap = {
[POPUP_EVENT.CONFIRM](dataItem) { // 确认事件
_handle(dataItem, options.confirmFilter);
},
[POPUP_EVENT.HIDE](dataItem) { // 隐藏浮窗
_closeCallback(dataItem, options.hideFilter);
},
[POPUP_EVENT.CLOSE](dataItem) { // 关闭浮窗
_closeCallback(dataItem, options.closeFilter);
typeof timeout !== 'undefined' && clearTimeout(timeout); // 防重
timeout = setTimeout(() => {
callFn(closeCb || dataItem, dataItem);
}, 0);
},
[POPUP_EVENT.CANCEL](dataItem) { // 取消事件
_handle(dataItem, options.cancelFilter);
}
};
let _keys = Object.keys(eventMap);
for (let i = 0; i < _keys.length; i++) {
const _key = _keys[i];
popup.$on(_key, eventMap[_key]);
}
/**
* 关闭或隐藏浮窗的回调
*
* @param {*} dataItem 数据
* @param {*} _filter 数据过滤器
* @returns {Promise}
*/
function _closeCallback(dataItem, _filter) {
return getBackData(_filter || dataItem, dataItem)
.then((_res) => {
for (let i = 0; i < _keys.length; i++) {
const _key = _keys[i];
popup.$off(_key, eventMap[_key]);
}
resolve(_res);
});
}
/**
* 关闭或隐藏浮窗的回调
* @param {*} dataItem 数据
* @param {*} _filter 数据过滤器
*/
function _handle(dataItem, _filter) {
getBackData(_filter || dataItem, dataItem)
.then((_res) => {
if (options.showFlag === 'show') { // 隐藏
_that.hide(options.key);
} else { // 关闭
_that.closePopup(options.key);
}
resolve(_res);
});
}
});
}
/**
* 执行popup的方法
* @param {*} key popup所以的key
* @param {*} type 执行的类型
* @param {*} param 参数
* @param {*} isReserve 是否保留
* @memberof PopupBase
* @returns {Boolean}
*/
_handlePopup(key, type, param, isReserve) {
let _that = this;
let popup = _that._getPopup(key);
if (popup) {
!isReserve && _that._removePopup(key);
popup && popup[type](param);
return true;
}
return false;
}
/**
* 用弹窗打开组件
* @param {Type<T>} component 组件
* @param {IPopupOptions} [options] 弹窗及组件选项
* @returns {T}
* @memberof PopupCommon
*/
_initPopup(component, options) {
let _that = this;
options = _that.getOptions(options);
return _that.sPopup.createPopup(component, options);
}
/**
* 移除popup
* @param {string} [key='default'] 缓存popup的引用key
* @param {Type<T>} component 组件
* @param {IPopupOptions} [options] 弹窗及组件选项
* @param {IPopupOptions} isCache 是否缓存
* @returns {undefined|popup}
* @memberof PopupBase
*/
async _addPopup(key, component, options, isCache) {
let _that = this;
key = key || 'default';
let _popup = isCache && _that._getPopup(key);
isCache && _popup && _popup.close(key); // 先关闭再创建
_popup = await _that._initPopup(component, options);
if (isCache) {
_that.close(key);
_that._cache[key] = _popup;
}
return _popup;
}
/**
* 移除popup
* @param {string} [key='default'] 缓存popup的引用key
* @memberof PopupBase
*/
_removePopup(key) {
let _that = this;
delete _that._cache[key || 'default'];
}
/**
* 获取popup
* @param {string} [key='default'] 缓存popup的引用key
* @returns {undefined|popup}
* @memberof PopupBase
*/
_getPopup(key) {
key = key || 'default';
let _that = this;
return _that._cache[key];
}
/**
* 初始化PopupCore
* @param {*} Vue vue
* @memberof PopupBase
*/
_setSPopup(Vue) {
let _that = this;
if (!_that.sPopup) {
let sPopup = new PopupCore(Vue);
sPopup._getParent = () => {
return _that._getParent && _that._getParent();
};
_that.sPopup = sPopup;
} else {
_that.sPopup._initMountCom(Vue);
}
}
/**
* 获取组件数据
* @param {any} component 组件
* @param {any} options 选项
* @param {Function} cb 初始化完成后的回调方法
* @returns {Promise}
*/
popupData(component, options, cb) {
let _that = this;
let _options = _that.getOptions(options);
if (_options.showFlag === 'show') {
_that.show(_options.key);
} else {
_that.close(_options.key); // 清空上次的popup
}
let res = new Promise((resolve, reject) => {
let popup = _that._getPopup(_options.key); // 获取上次的popup对象
if (!popup || !popup.popup || _options.showFlag !== 'show') {
_that.openPopup(component, Object.assign({}, _options), true).then((back) => { // 缓存上次初始化
Object.assign(res, back);
back.popup && _that._initWatch(back.popup, _options).then(resolve, reject);
callFn(cb, [back.popup]);
});
} else {
_that._initWatch(popup.popup, _options).then(resolve, reject);
callFn(cb, [popup.popup]);
}
});
return res;
}
/**
* 打开浮窗
* @param {Type<T>} component 组件
* @param {IPopupOptions} [options] 弹窗及组件选项
* @param {IPopupOptions} isCache 是否缓存
* @return {Object|undefined}
*/
openPopup(component, options, isCache) {
options = options || {};
return this._addPopup(options.key, component, options, isCache);
}
/**
* 更新输入数据
* @param {String} [key='default'] popup的key
* @param {IKeyValue} props 数据
* @memberof PopupCommon
* @returns {Boolean}
*/
updateProps(key, props) {
return this._handlePopup(key, 'updateProps', props, true);
}
/**
* 更新data输入数据
* @param {String} [key='default'] popup的key
* @param {IKeyValue} data 数据
* @memberof PopupCommon
* @returns {Boolean}
*/
updateData (key, data) {
return this._handlePopup(key, 'updateData', data, true);
}
/**
* 显示指定的key的popup
* @param {String} [key='default'] popup的key
* @returns {Boolean}
*/
show(key) {
return this._handlePopup(key, 'show', null, true);
}
/**
* 隐藏指定的key的popup
* @param {String} [key='default'] popup的key
* @returns {Boolean}
*/
hide(key) {
return this._handlePopup(key, 'hide', null, true);
}
/**
* 关闭指定的key的popup
* @param {String} [key='default'] popup的key
* @returns {Boolean}
*/
closePopup(key) {
return this._handlePopup(key, 'closePopup');
}
close(key) {
return this._handlePopup(key, 'close');
}
/**
* 关闭全部
*/
closeAll() {
let _that = this;
let _cache = _that._cache;
for (const key in _cache) {
if (_cache.hasOwnProperty(key)) {
_that.close(key);
}
}
}
/**
* 安装
* @param {Vue} Vue Vue
* @param {Object} options 初始化参数
* @memberof PopupCommon
*/
install(Vue, options) {
let _that = this;
_that._setSPopup(Vue);
super.install(Vue, options);
}
}