import { deepCopy } from '@/core'; import { IAbility, ICtrlActionResult, IEvent, IParam, IPortletControllerParams, IPortletModel, IViewLogicInput, } from '@/core/interface'; import { IMDCtrlAbility, IPortletAbility, } from '@/core/interface/widgets/ability'; import { IPortletController } from '@/core/interface/widgets/controller'; import { PortletActionType } from '@/core/interface/widgets/event'; import { IPortletStore } from '@/core/interface/widgets/store'; import { DECtrlController } from './de-ctrl-controller'; /** * 门户部件控制器 * * @export * @class PortletController * @extends {(DECtrlController)} * @implements {IPortletController} * @template A */ export class PortletController extends DECtrlController implements IPortletController { /** * Creates an instance of DashboardController. * @param {IPortletControllerParams} params * @memberof PortletController */ public constructor( params: IPortletControllerParams ) { super(params); this.ctrlInit(params); } /** * 处理部件初始化 * * @protected * @param {IPortletControllerParams} params * @memberof PortletController */ protected processCtrlInit( params: IPortletControllerParams ) { super.processCtrlInit(params); Object.assign(this.store, { data: {}, toolbarItems: this.model.toolbarItems || [], actions: this.model.actions || [], }); this.initPortletArray(); } /** * 初始化后(对store做处理)除直接内容不抛出ctrl-init * * @protected * @param {IPortletControllerParams} params * @memberof PortletController */ protected afterCtrlInit( params: IPortletControllerParams ) { this.initStore(); // 没有加载能力的直接抛能力出去 if ( this.model.portletType === 'RAWITEM' || this.model.portletType === 'ACTIONBAR' || this.model.portletType === 'HTML' ) { this.evt.emit('ctrlInit', this.name, this.getAbility()); } } /** * 容器内门户部件数组 * * @private * @type {any[]} * @memberof PortletController */ private portletArray: any[] = []; /** * 初始化容器内门户部件数组 * * @memberof PortletController */ protected initPortletArray() { const { portletArray } = this.model; if (portletArray && portletArray.length > 0) { this.model.portletArray.forEach((portlet: any) => { if ( portlet.type !== 'RAWITEM' && portlet.type !== 'ACTIONBAR' && portlet.type !== 'HTML' ) { this.portletArray.push(portlet); } }); } } /** * 处理门户部件 * * @param {IEvent} actionParam * @memberof PortletController */ public handleComponentAction(actionParam: IEvent): void { const { name, action, data } = actionParam; switch (action) { case 'portletAction': this.handlePortletUIAction(data.event, data.logic); break; } } /** * 处理portlet界面行为 * * @param {MouseEvent} event 事件源 * @param {IViewLogicInput} logic 逻辑 * @memberof PortletController */ private handlePortletUIAction( event: MouseEvent, logic: IViewLogicInput ): void { const { context, viewParams } = this.store; App.getViewLogicHelper().executeViewLogic( context, viewParams, this.getData(), event, this.getAbility(), logic ); } /** * 设置子能力 * * @param {string} name * @param {IAbility} subAbility * @memberof PortletController */ public setSubAbility(name: string, subAbility: IAbility) { this.subAbilityCenter.set(name, subAbility); // 门户容器的话等内部所有门户部件抛出能力再初始化完成 if (this.portletArray.length > 0) { if (this.subAbilityCenter.size == this.portletArray.length) { this.evt.emit('ctrlInit', this.name, this.getAbility()); } } else { // 不是容器的话则直接初始化完成 this.evt.emit('ctrlInit', this.name, this.getAbility()); } } /** * 加载子部件 * * @memberof PortletController */ public async load(opts: IParam = {}): Promise { return new Promise((resolve: any, reject: any) => { const promiseArray: any = []; // 容器的话需要内部全部加载 if (this.portletArray.length > 0) { this.portletArray.forEach((item: any) => { const ability = this.getPortletCtrlAbility(item.name); if (ability) { const promise = ability.load(opts); promiseArray.push(promise); } }); } else { // 不是容器的话直接获取自身能力 const name = Object.is(this.model.portletType, 'VIEW') ? this.model.name : this.name; const ability = this.getPortletCtrlAbility(name); if (ability) { const promise = ability.load(opts); promiseArray.push(promise); } } const { context } = this.store; const tempContext = deepCopy(context); this.beforeAsyncAction('load', tempContext, {}); Promise.all(promiseArray) .then((resArray: any) => { const _data: any = []; resArray.forEach((response: any, resIndex: number) => { if (!response || !response.ok) { this.afterAsyncAction('load', response); return; } _data.push(response.rowData); }); const result = { ok: true, rowData: _data }; resolve(result); this.afterAsyncAction('load', _data); }) .catch((response: any) => { reject(response); }); }); } /** * 获取门户部件能力 * * @protected * @return {*} {(IMDCtrlAbility)} * @memberof PortletController */ protected getPortletCtrlAbility(name: string): IMDCtrlAbility { return this.getSubAbility(name); } /** * 获取部件能力 * * @return {*} {A} * @memberof PortletController */ public getAbility(): IPortletAbility { return { ...super.getAbility(), load: this.load.bind(this), }; } }