|
|
|
import { isFunction, isNull, isNotNull, isArray, each, isWidget, extend, init, isEmpty, remove } from "./2.base";
|
|
|
|
import { OB } from "./3.ob";
|
|
|
|
import { Widget } from "./4.widget";
|
|
|
|
|
|
|
|
const moduleInjection = {}, moduleInjectionMap = {
|
|
|
|
components: {},
|
|
|
|
constants: {},
|
|
|
|
stores: {},
|
|
|
|
services: {},
|
|
|
|
models: {},
|
|
|
|
providers: {},
|
|
|
|
};
|
|
|
|
|
|
|
|
export function module(xtype, cls) {
|
|
|
|
if (isNotNull(moduleInjection[xtype])) {
|
|
|
|
_global.console && console.error(`module: [${xtype}] 已经注册过了`);
|
|
|
|
} else {
|
|
|
|
if (isFunction(cls)) {
|
|
|
|
cls = cls();
|
|
|
|
}
|
|
|
|
for (const k in moduleInjectionMap) {
|
|
|
|
if (cls[k]) {
|
|
|
|
for (const key in cls[k]) {
|
|
|
|
if (!moduleInjectionMap[k]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!moduleInjectionMap[k][key]) {
|
|
|
|
moduleInjectionMap[k][key] = [];
|
|
|
|
}
|
|
|
|
moduleInjectionMap[k][key].push({
|
|
|
|
version: cls[k][key],
|
|
|
|
moduleId: xtype,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
moduleInjection[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => Modules.getModule(xtype);
|
|
|
|
}
|
|
|
|
|
|
|
|
const constantInjection = {};
|
|
|
|
export function constant(xtype, cls) {
|
|
|
|
if (isNotNull(constantInjection[xtype])) {
|
|
|
|
_global.console && console.error(`constant: [${xtype}]已经注册过了`);
|
|
|
|
} else {
|
|
|
|
constantInjection[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => Constants.getConstant(xtype);
|
|
|
|
}
|
|
|
|
|
|
|
|
const modelInjection = {};
|
|
|
|
export function model(xtype, cls) {
|
|
|
|
if (isNotNull(modelInjection[xtype])) {
|
|
|
|
_global.console && console.error(`model: [${xtype}] 已经注册过了`);
|
|
|
|
} else {
|
|
|
|
modelInjection[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return config => Models.getModel(xtype, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
const storeInjection = {};
|
|
|
|
export function store(xtype, cls) {
|
|
|
|
if (isNotNull(storeInjection[xtype])) {
|
|
|
|
_global.console && console.error(`store: [${xtype}] 已经注册过了`);
|
|
|
|
} else {
|
|
|
|
storeInjection[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return config => Stores.getStore(xtype, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
const serviceInjection = {};
|
|
|
|
export function service(xtype, cls) {
|
|
|
|
if ((serviceInjection[xtype])) {
|
|
|
|
_global.console && console.error(`service: [${xtype}] 已经注册过了`);
|
|
|
|
}
|
|
|
|
|
|
|
|
serviceInjection[xtype] = cls;
|
|
|
|
|
|
|
|
return config => Services.getService(xtype, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
const providerInjection = {};
|
|
|
|
export function provider(xtype, cls) {
|
|
|
|
if ((providerInjection[xtype])) {
|
|
|
|
_global.console && console.error(`provider: [${xtype}] 已经注册过了`);
|
|
|
|
} else {
|
|
|
|
providerInjection[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return config => Providers.getProvider(xtype, config);
|
|
|
|
}
|
|
|
|
|
|
|
|
const configFunctions = OB.configFunctions = {};
|
|
|
|
const runConfigFunction = (type, configFn) => {
|
|
|
|
if (!type || !configFunctions[type]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
let queue = [];
|
|
|
|
if (configFn) {
|
|
|
|
queue = configFunctions[type].filter(conf => conf.fn === configFn);
|
|
|
|
configFunctions[type] = configFunctions[type].filter(conf => conf.fn !== configFn);
|
|
|
|
} else {
|
|
|
|
queue = configFunctions[type];
|
|
|
|
delete configFunctions[type];
|
|
|
|
}
|
|
|
|
|
|
|
|
const dependencies = Providers.getProvider("bi.provider.system").getDependencies();
|
|
|
|
const modules = moduleInjectionMap.components[type]
|
|
|
|
|| moduleInjectionMap.constants[type]
|
|
|
|
|| moduleInjectionMap.services[type]
|
|
|
|
|| moduleInjectionMap.stores[type]
|
|
|
|
|| moduleInjectionMap.models[type]
|
|
|
|
|| moduleInjectionMap.providers[type];
|
|
|
|
for (let i = 0; i < queue.length; i++) {
|
|
|
|
const conf = queue[i];
|
|
|
|
const version = conf.opt.version;
|
|
|
|
const fn = conf.fn;
|
|
|
|
if (modules && version) {
|
|
|
|
let findVersion = false;
|
|
|
|
let module;
|
|
|
|
for (let j = 0; j < modules.length; j++) {
|
|
|
|
module = modules[j];
|
|
|
|
if (module && dependencies[module.moduleId] && module.version === version) {
|
|
|
|
const minVersion = dependencies[module.moduleId].minVersion,
|
|
|
|
maxVersion = dependencies[module.moduleId].maxVersion;
|
|
|
|
if (minVersion && (moduleInjection[module.moduleId].version || version) < minVersion) {
|
|
|
|
findVersion = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (maxVersion && (moduleInjection[module.moduleId].version || version) > maxVersion) {
|
|
|
|
findVersion = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (findVersion === true) {
|
|
|
|
_global.console && console.error(`moduleId: [${module.moduleId}] 接口: [${type}] 接口版本: [${version}] 已过期,版本要求为:`, dependencies[module.moduleId], "=>", moduleInjection[module.moduleId]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (constantInjection[type]) {
|
|
|
|
constantInjection[type] = fn(constantInjection[type]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (providerInjection[type]) {
|
|
|
|
if (!providers[type]) {
|
|
|
|
providers[type] = new providerInjection[type]();
|
|
|
|
}
|
|
|
|
if (providerInstance[type]) {
|
|
|
|
delete providerInstance[type];
|
|
|
|
}
|
|
|
|
fn(providers[type]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
BI.Plugin.configWidget(type, fn, conf.opt);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export function config(type, configFn, opt) {
|
|
|
|
if (isFunction(type)) {
|
|
|
|
opt = configFn;
|
|
|
|
configFn = type;
|
|
|
|
type = "bi.provider.system";
|
|
|
|
}
|
|
|
|
opt = opt || {};
|
|
|
|
|
|
|
|
// 系统配置直接执行
|
|
|
|
if ("bi.provider.system" === type) {
|
|
|
|
if (!providers[type]) {
|
|
|
|
providers[type] = new providerInjection[type]();
|
|
|
|
}
|
|
|
|
// 如果config被重新配置的话,需要删除掉之前的实例
|
|
|
|
if (providerInstance[type]) {
|
|
|
|
delete providerInstance[type];
|
|
|
|
}
|
|
|
|
|
|
|
|
return configFn(providers[type]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!configFunctions[type]) {
|
|
|
|
configFunctions[type] = [];
|
|
|
|
}
|
|
|
|
configFunctions[type].push({
|
|
|
|
fn: configFn,
|
|
|
|
opt,
|
|
|
|
});
|
|
|
|
|
|
|
|
if (opt.immediately) {
|
|
|
|
return runConfigFunction(type, configFn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getReference(type, fn) {
|
|
|
|
return BI.Plugin.registerObject(type, fn);
|
|
|
|
}
|
|
|
|
|
|
|
|
const actions = {};
|
|
|
|
const globalAction = [];
|
|
|
|
export function action(type, actionFn) {
|
|
|
|
if (isFunction(type)) {
|
|
|
|
globalAction.push(type);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
remove(globalAction, idx => globalAction.indexOf(actionFn) === idx);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (!actions[type]) {
|
|
|
|
actions[type] = [];
|
|
|
|
}
|
|
|
|
actions[type].push(actionFn);
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
remove(actions[type], idx => actions[type].indexOf(actionFn) === idx);
|
|
|
|
if (actions[type].length === 0) {
|
|
|
|
delete actions[type];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const points = {};
|
|
|
|
export function point(type, action, pointFn, after) {
|
|
|
|
if (!points[type]) {
|
|
|
|
points[type] = {};
|
|
|
|
}
|
|
|
|
if (!points[type][action]) {
|
|
|
|
points[type][action] = {};
|
|
|
|
}
|
|
|
|
if (!points[type][action][after ? "after" : "before"]) {
|
|
|
|
points[type][action][after ? "after" : "before"] = [];
|
|
|
|
}
|
|
|
|
points[type][action][after ? "after" : "before"].push(pointFn);
|
|
|
|
}
|
|
|
|
|
|
|
|
export const Modules = {
|
|
|
|
getModule (type) {
|
|
|
|
if (!moduleInjection[type]) {
|
|
|
|
_global.console && console.error(`module: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return moduleInjection[type];
|
|
|
|
},
|
|
|
|
getAllModules () {
|
|
|
|
return moduleInjection;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export const Constants = {
|
|
|
|
getConstant (type) {
|
|
|
|
if (isNull(constantInjection[type])) {
|
|
|
|
_global.console && console.error(`constant: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
runConfigFunction(type);
|
|
|
|
|
|
|
|
return isFunction(constantInjection[type]) ? constantInjection[type]() : constantInjection[type];
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
function callPoint(inst, types) {
|
|
|
|
types = isArray(types) ? types : [types];
|
|
|
|
each(types, (idx, type) => {
|
|
|
|
if (points[type]) {
|
|
|
|
for (const action in points[type]) {
|
|
|
|
const bfns = points[type][action].before;
|
|
|
|
if (bfns) {
|
|
|
|
BI.aspect.before(inst, action, (function (bfns) {
|
|
|
|
return function () {
|
|
|
|
for (let i = 0, len = bfns.length; i < len; i++) {
|
|
|
|
try {
|
|
|
|
bfns[i].apply(inst, arguments);
|
|
|
|
} catch (e) {
|
|
|
|
_global.console && console.error(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}(bfns)));
|
|
|
|
}
|
|
|
|
const afns = points[type][action].after;
|
|
|
|
if (afns) {
|
|
|
|
BI.aspect.after(inst, action, (function (afns) {
|
|
|
|
return function () {
|
|
|
|
for (let i = 0, len = afns.length; i < len; i++) {
|
|
|
|
try {
|
|
|
|
afns[i].apply(inst, arguments);
|
|
|
|
} catch (e) {
|
|
|
|
_global.console && console.error(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}(afns)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export const Models = {
|
|
|
|
getModel (type, config) {
|
|
|
|
if (!modelInjection[type]) {
|
|
|
|
_global.console && console.error(`model: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
runConfigFunction(type);
|
|
|
|
const inst = new modelInjection[type](config);
|
|
|
|
inst._constructor && inst._constructor(config);
|
|
|
|
inst.mixins && callPoint(inst, inst.mixins);
|
|
|
|
callPoint(inst, type);
|
|
|
|
|
|
|
|
return inst;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const stores = {};
|
|
|
|
export const Stores = {
|
|
|
|
getStore (type, config) {
|
|
|
|
if (!storeInjection[type]) {
|
|
|
|
_global.console && console.error(`store: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
if (stores[type]) {
|
|
|
|
return stores[type];
|
|
|
|
}
|
|
|
|
const inst = stores[type] = new storeInjection[type](config);
|
|
|
|
inst._constructor && inst._constructor(config, () => {
|
|
|
|
delete stores[type];
|
|
|
|
});
|
|
|
|
callPoint(inst, type);
|
|
|
|
|
|
|
|
return inst;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const services = {};
|
|
|
|
export const Services = {
|
|
|
|
getService: (type, config) => {
|
|
|
|
if (!serviceInjection[type]) {
|
|
|
|
_global.console && console.error(`service: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
if (services[type]) {
|
|
|
|
return services[type];
|
|
|
|
}
|
|
|
|
services[type] = new serviceInjection[type](config);
|
|
|
|
callPoint(services[type], type);
|
|
|
|
|
|
|
|
return services[type];
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const providers = {},
|
|
|
|
providerInstance = {};
|
|
|
|
export const Providers = {
|
|
|
|
getProvider: (type, config) => {
|
|
|
|
if (!providerInjection[type]) {
|
|
|
|
_global.console && console.error(`provider: [${type}] 未定义`);
|
|
|
|
}
|
|
|
|
runConfigFunction(type);
|
|
|
|
if (!providers[type]) {
|
|
|
|
providers[type] = new providerInjection[type]();
|
|
|
|
}
|
|
|
|
if (!providerInstance[type] && providers[type].$get) {
|
|
|
|
providerInstance[type] = new (providers[type].$get())(config);
|
|
|
|
}
|
|
|
|
|
|
|
|
return providerInstance[type];
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
export const Actions = {
|
|
|
|
runAction (type, event, config) {
|
|
|
|
each(actions[type], (i, act) => {
|
|
|
|
try {
|
|
|
|
act(event, config);
|
|
|
|
} catch (e) {
|
|
|
|
_global.console && console.error(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
runGlobalAction () {
|
|
|
|
const args = [].slice.call(arguments);
|
|
|
|
each(globalAction, (i, act) => {
|
|
|
|
try {
|
|
|
|
act(...args);
|
|
|
|
} catch (e) {
|
|
|
|
_global.console && console.error(e);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const kv = {};
|
|
|
|
export function shortcut(xtype, cls) {
|
|
|
|
if (isNotNull(kv[xtype])) {
|
|
|
|
_global.console && console.error(`组件: [${xtype}] 已经注册过了`);
|
|
|
|
}
|
|
|
|
if (cls) {
|
|
|
|
cls.xtype = xtype;
|
|
|
|
}
|
|
|
|
kv[xtype] = cls;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 根据配置属性生成widget
|
|
|
|
const createRealWidget = (config, context, lazy) => {
|
|
|
|
const Cls = isFunction(config.type) ? config.type : kv[config.type];
|
|
|
|
|
|
|
|
if (!Cls) {
|
|
|
|
throw new Error(`组件: [${config.type}] 未定义`);
|
|
|
|
}
|
|
|
|
let pushed = false;
|
|
|
|
const widget = new Cls();
|
|
|
|
widget._context = Widget.context || context;
|
|
|
|
if (!Widget.context && context) {
|
|
|
|
pushed = true;
|
|
|
|
Widget.pushContext(context);
|
|
|
|
}
|
|
|
|
callPoint(widget, config.type);
|
|
|
|
widget._initProps(config);
|
|
|
|
widget._initRoot();
|
|
|
|
widget._constructed();
|
|
|
|
// if (!lazy || config.element || config.root) {
|
|
|
|
widget._lazyConstructor();
|
|
|
|
// }
|
|
|
|
pushed && Widget.popContext();
|
|
|
|
|
|
|
|
return widget;
|
|
|
|
};
|
|
|
|
|
|
|
|
export function createWidget(item, options, context, lazy) {
|
|
|
|
item || (item = {});
|
|
|
|
if (isWidget(options)) {
|
|
|
|
context = options;
|
|
|
|
options = {};
|
|
|
|
} else {
|
|
|
|
options || (options = {});
|
|
|
|
}
|
|
|
|
|
|
|
|
let el, w;
|
|
|
|
if (item.type || options.type) {
|
|
|
|
el = extend({}, options, item);
|
|
|
|
} else if (item.el && (item.el.type || options.type)) {
|
|
|
|
el = extend({}, options, item.el);
|
|
|
|
}
|
|
|
|
let elType;
|
|
|
|
if (el) {
|
|
|
|
elType = (el.type && el.type.xtype) || el.type;
|
|
|
|
runConfigFunction(elType);
|
|
|
|
}
|
|
|
|
|
|
|
|
// 先把准备环境准备好
|
|
|
|
init();
|
|
|
|
|
|
|
|
if (isEmpty(item) && isEmpty(options)) {
|
|
|
|
return createWidget({
|
|
|
|
type: "bi.layout",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if (isWidget(item)) {
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
if (el) {
|
|
|
|
w = BI.Plugin.getWidget(elType, el);
|
|
|
|
const wType = (w.type && w.type.xtype) || w.type;
|
|
|
|
if (wType === elType) {
|
|
|
|
if (BI.Plugin.hasObject(elType)) {
|
|
|
|
if (!w.listeners || isArray(w.listeners)) {
|
|
|
|
w.listeners = (w.listeners || []).concat([{
|
|
|
|
eventName: BI.Events.MOUNT,
|
|
|
|
action: () => {
|
|
|
|
BI.Plugin.getObject(elType, this);
|
|
|
|
},
|
|
|
|
}]);
|
|
|
|
} else {
|
|
|
|
w.listeners[BI.Events.MOUNT] = [
|
|
|
|
() => {
|
|
|
|
BI.Plugin.getObject(elType, this);
|
|
|
|
}
|
|
|
|
].concat(w.listeners[BI.Events.MOUNT] || []);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return createRealWidget(w, context, lazy);
|
|
|
|
}
|
|
|
|
|
|
|
|
return createWidget(w, options, context, lazy);
|
|
|
|
}
|
|
|
|
if (isWidget(item.el)) {
|
|
|
|
return item.el;
|
|
|
|
}
|
|
|
|
throw new Error("组件:无法根据item创建组件", item);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function _lazyCreateWidget (item, options, context) {
|
|
|
|
return createWidget(item, options, context, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function createElement() {
|
|
|
|
const widget = createWidget.apply(this, arguments);
|
|
|
|
|
|
|
|
return widget.element;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getResource(type, config) {
|
|
|
|
if (isNotNull(constantInjection[type])) {
|
|
|
|
return Constants.getConstant(type);
|
|
|
|
}
|
|
|
|
if (modelInjection[type]) {
|
|
|
|
return Models.getModel(type, config);
|
|
|
|
}
|
|
|
|
if (storeInjection[type]) {
|
|
|
|
return Stores.getStore(type, config);
|
|
|
|
}
|
|
|
|
if (serviceInjection[type]) {
|
|
|
|
return Services.getService(type, config);
|
|
|
|
}
|
|
|
|
if (providerInjection[type]) {
|
|
|
|
return Providers.getProvider(type, config);
|
|
|
|
}
|
|
|
|
throw new Error(`未知类型: [${type}] 未定义`);
|
|
|
|
}
|