const JMAlertBase = require('JMAlertBase'); /** * 弹框控制器 */ cc.Class({ extends: cc.Component, properties: { _alertList: { default: [], type: JMAlertBase } }, /** * 生命周期。子类需要调用this._super() * * @author Pyden * @date 2019-03-25 */ onEnable () { this.node.on('e_alert_pop', this._handlePopAlert, this); }, /** * 生命周期。子类需要调用this._super() * * @author Pyden * @date 2019-03-25 */ onDisable () { this.node.off('e_alert_pop', this._handlePopAlert, this); }, /** * 返回键被点击。最后一个弹框会吃掉返回键响应 * * @author Pyden * @date 2019-03-25 * @returns 是否吃点返回键响应 */ backKeyOnClicked () { let length = this._alertList.length; if (length > 0) { let alert = this._alertList[length - 1]; alert.backKeyOnClicked(); return true; } else { return false; } }, /** * 弹出指定弹框 * * @author Pyden * @date 2019-03-22 * @param {JMAlertBase} alert 弹框 */ pushAlert (alert) { if (!cc.isValid(alert) || !cc.isValid(this.node)) { return false; } let zIndex = alert.alertZIndex; this.node.addChild(alert.node, zIndex); this._alertList.push(alert); cc.game.emit('e_ui_push_alert', {alert: alert}); return true; }, /** * 关闭指定弹框 * * @author Pyden * @date 2019-03-22 * @param {JMAlertBase} alert 弹框 */ popAlert (alert) { let length = this._alertList.length; for (let i = length - 1; i >= 0; i--) { if (this._alertList[i] === alert) { this._alertList.splice(i, 1); break; } } alert.node.destroy(); let topAlert = this._alertList[this._alertList.length - 1]; cc.game.emit('e_ui_pop_alert', {alertId: alert.id, alertData: alert.data, topAlert: topAlert}); }, /** * 关闭全部弹框 * 不能在hideDone的触发事件中调用popAllAlert * 会造成栈溢出,需要加个scheduleOnce避免无限递归调用 * * @author Pyden * @date 2019-03-22 * @param {boolean} forceClose 强制关闭 */ popAllAlert (forceClose) { let length = this._alertList.length; for (let i = length - 1; i >= 0; i--) { let alert = this._alertList[i]; if (alert.alertZIndex < 100 || forceClose) { alert.close(); } } }, /** * 关闭指定弹框 * * @author Wetion * @date 2019-05-23 * @param {Number} alertId 弹框ID */ closeAlert (alertId) { let length = this._alertList.length; for (let i = length - 1; i >= 0; i--) { let alert = this._alertList[i]; if (alert.id === alertId) { alert.close(); break; } } }, /** * 获取已弹出的弹框 * * @author Pyden * @date 2019-03-28 * @param {JMC.ALERT_ID} alertId 弹框 Id * @returns {JMAlertBase} 弹框组件 */ getAlert (alertId) { for (let v of this._alertList) { if (v.id == alertId) { return v; } } return undefined; }, /** * 获取已弹出的弹窗数量 * * @author libo * @date 2019-05-05 * @returns number 弹窗数量 */ getAlertCount () { return this._alertList.length; }, /** * 弹出普通弹框 * * @author Pyden * @date 2019-03-28 * @param {JMC.ALERT_ID} alertId 弹框 Id * @param {any} userdata 弹框相关的数据 * @param {function} cb 回调,参数有:alert, eventKey, eventData。cb为空时,点击弹框任意交互都关闭弹框 * @example ```js let alertId = JMC.ALERT_ID.ITEM_INFO; let userdata = {param1: 1, param2: 2, goodsData: goodsData}; let cb = (alert, eventKey, eventData) => { if (eventKey == 'clickedLeft') { // 左边按钮点击 } else if (eventKey == 'clickedRight') { // 右边按钮点击 } else { // 事件的默认处理:忽略 error、willShow 时间,其它事件都直接关闭弹框 alert.alertDefaultCallback(eventKey, eventData); } }; this.showNormalAlert(alertId, userdata, cb); */ showNormalAlert (alertId, userdata, cb) { let alertData = G.AlertMgr.getConfig(alertId, userdata); this.showAlert( 'edt_prefab/public/prefab_normal_alert', alertData, cb, true ); }, /** * 弹出弹框 * * @author Pyden * @date 2019-04-12 * @param {String} prefabPath 预制体的路径 * @param {Object} alertData 弹框的数据,用在reloadData * @param {Function} cb 回调,参数有:alert, eventKey, eventData。cb为空时,点击弹框任意交互都关闭弹框 * @example ```js let alertId = JMC.ALERT_ID.ITEM_INFO; let userdata = {param1: 1, param2: 2, goodsData: goodsData}; let alertData = G.AlertMgr.getConfig(alertId, userdata); let cb = (alert, eventKey, eventData) => { if (eventKey == 'clickedLeft') { // 左边按钮点击 } else if (eventKey == 'clickedRight') { // 右边按钮点击 } else { // 事件的默认处理:忽略 error、willShow 时间,其它事件都直接关闭弹框 alert.alertDefaultCallback(eventKey, eventData); } }; this.showAlert( 'edt_prefab/public/prefab_normal_alert', alertData, cb ); */ showAlert (prefabPath, alertData, cb, cache = false) { G.LogUtils.warn('showAlert', prefabPath); G.AppUtils.getSceneCtrl().showLoadingAlert(); let temp = undefined; cc.loader.loadRes(prefabPath, cc.Prefab, (completedCount, totalCount, item)=>{ temp = G.AppUtils.getLoadProgressInfo(temp, completedCount, totalCount); G.AppUtils.getSceneCtrl().updateLoadingProgress(temp.precent * 100, 100, item); }, (err, prefab) => { G.AppUtils.getSceneCtrl().updateLoadingProgress(100, 100, undefined); if (err) { G.AppUtils.getSceneCtrl().addToast('网络异常!'); G.LogUtils.error('[showAlert]', err); if (cb) { cb(undefined, 'error', err); } return; } let node = cc.instantiate(prefab); let alert = node.getComponent('JMAlertBase'); if (cb) { cb(alert, 'willShow', undefined); } let ret = this.pushAlert(alert); if (!ret) { return; } // 因为reloadData如果出错会导致游戏闪屏,所以加上try catch try { alert.reloadData(alertData, cb); } catch (error) { G.LogUtils.error('AlertCtrl showAlert error:', error); } if (!cache) { cc.loader.releaseRes(prefabPath); } }); }, // ---------------- 私有方法分割线 ---------------- /** * 收到弹框关闭的事件。只能收到子节点的事件 * * @author Pyden * @date 2019-03-25 * @param {cc.Event} event */ _handlePopAlert (event) { let alert = event.getUserData(); this.popAlert(alert); } });