UNPKG

mutants-appfx

Version:

appfx module

182 lines (163 loc) 3.95 kB
import React from 'react'; import { observable, action, runInAction } from 'mobx'; import { clientType } from 'mutants-microfx'; import Expression from '../expression'; import DataProviderManager from '../DataProviderManager'; import UIFunction from '../UIFunction'; const NoView = () => { return (<div>No View!</div>) } export default class ViewModel { mid; viewType; // 用来rules判断view的特征 @observable items; // 视图对象,比如栏目、滤设、工具条等 // 注意:data是vm的私有变量view不应该使用 @observable list; // 视图加载的数据集合,data是其中的一行的DM实例 @observable data; // 视图加载的数据 @observable state; // 视图状态,例如:只读、新增、修改... static viewTypes = new Map(); static viewModelTypes = new Map(); get clientType() { return clientType; } //获取VM getViewItem(viewItemType) { return this.items.find(item => item.type === viewItemType); } constructor(viewType, mid) { this.viewType = viewType; this.mid = mid; } parseExpr(txt) { return new Expression(txt); } execExpr(expr) { return expr.exec({ ...this.data, vm: this, uifunction: UIFunction.get(this.mid) }); } @action async loadData(data, list) { this.data = data; this.list = list; } static getView({ pid, view, views = {} }) { const viewTypes = ViewModel.viewTypes.get((views[pid] || view).name); return viewTypes[pid] || viewTypes.index; } async refresh({ sysid, mid, pid, view, views, ...other }) { await ViewModel.getViewInfo({ sysid, mid, pid, view: (views[pid] || view).name, ...other }, this); } static async getViewInfo({ sysid, mid, pid, view, views = {}, ...other }, vm, singles = {}) { const metadata = (await DataProviderManager.getViewInfo({ sysid, mid, pid, view: (views[pid] || view).name, ...other })); const ViewModels = ViewModel.viewModelTypes.get((views[pid] || view).name) || []; runInAction(() => { vm.items = ViewModels.map(VM => { const subVmKey = '$sub_' + VM.name; if (VM.model === 'single' && singles[subVmKey]) { return singles[subVmKey]; } let item; // 不要给name赋值,name是实例的名字,可以创建多个实例 VM.model._tname = VM.name; if (typeof VM.model.fromJS === 'function') { item = VM.model.fromJS(vm, metadata); } else { item = new VM.model(vm); } if (VM.model === 'single') { singles[subVmKey] = item; } return item; }); }); } static async load({ mid, pid, view, views, ...other }, dataModel, listModel, singles) { const vmKey = '$vm_' + (views[pid] || view).name; const exists = singles[vmKey]; if (exists) { return exists; } const vm = new ViewModel((views[pid] || view).name, mid); vm.loadData(dataModel, listModel); await ViewModel.getViewInfo({ mid, pid, views, view, ...other }, vm, singles); singles[vmKey] = vm; return vm; } static registerViewModel(viewKey, View, ...ViewModels) { ViewModel.viewTypes.set(viewKey, typeof View === 'function' ? { index: { type: View } } : { index: View.index || { type: NoView }, ...Object.keys(View).reduce((ret, key) => ({ ...ret, [key]: typeof View[key] === 'function' ? { type: View[key] } : View[key] }), {}) }); ViewModel.viewModelTypes.set(viewKey, ViewModels.map(it => { if (typeof it === 'function') { return { name: it.name, model: it } } else { return it; } })); } }