mutants-appfx
Version:
appfx module
182 lines (163 loc) • 3.95 kB
JavaScript
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的特征
items; // 视图对象,比如栏目、滤设、工具条等
// 注意:data是vm的私有变量view不应该使用
list; // 视图加载的数据集合,data是其中的一行的DM实例
data; // 视图加载的数据
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)
});
}
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;
}
}));
}
}