const DefaultTag = 'default';
const defaultPriority = 0;
const __ = {
private: Symbol('private')
}
const controlClassMap = new Map();
/**
* 层级控制器 (实例化THING.App时自动初始化)
* @param {Object} app - 应用实例,包含 level、levelControlManager 等
* @public
*
* 初始化行为:
* - 启用默认控件
* - 为已有控件动态定义访问属性(this[name] 可读写)
*/
class LevelControls {
static setLevelControlClass(levelName, levelCondition, controlClass) {
controlClassMap.set(levelName, { condition: levelCondition, cls: controlClass });
};
constructor(app) {
this.app = app;
let _private = this[__.private] = {};
_private.controlsMap = new Map();
_private.addControlProperty = (name, condition, control) => {
let contorlOption = {
control,
condition,
tag: DefaultTag
};
_private.controlsMap.set(name, contorlOption);
Object.defineProperty(this, name, {
get: () => {
const controlParam = _private.controlsMap.get(name);
if (controlParam) {
return controlParam.control;
} else {
return null;
}
},
set: (control) => {
const controlParam = _private.controlsMap.get(name);
if (controlParam) {
this.addControl(controlParam.condition, name, control);
}
},
configurable: true
});
};
// Initialize the level control
controlClassMap.forEach((val, key) => {
app.level.levelControlManager.registerClass(val.cls, { condition: val.condition, name: key, tag: DefaultTag });
});
app.level.levelControlManager.enableControls(DefaultTag);
// 兼容campus原来的接口
const controls = app.level.levelControlManager.getControlsByTag(DefaultTag);
for (let i = 0; i < controls.length; i++) {
const control = controls[i];
const options = control.options;
_private.addControlProperty(options.name, options.condition, control);
}
}
/**
* 批量设置所有已注册控件的选项
* @param {string} option - 要设置的选项名
* @param {*} value - 要设置的值
* @public
*
* 遍历 private.controlsMap,将每个控件的对应 option 设置为 value。
*/
setControlOption(option, value) {
let _private = this[__.private];
_private.controlsMap.forEach((controlParam) => {
controlParam.control[option] = value;
})
}
/**
* 添加(注册)控件实例到 level 管理器,并在当前实例上建立访问属性
* @param {String} condition - 控件的启用条件
* @param {string} name - 控件名称(用于在 this 上创建属性)
* @param {DefaultLevelControl} control - 控件实例(需满足 isDefaultLevelControl)
* @param {Object} [options] - 注册时的额外选项(会与默认 tag 和优先级合并)
* @public
*
* 行为:
* - 若 control 不合法则忽略
* - 先注销同名控件(若存在)
* - 调用 app.level.register 注册控件
* - 在私有表中添加属性并在 this 上定义可访问属性
*/
addControl(condition, name, control, options) {
if (!control || !control.isDefaultLevelControl) {
return;
}
// unregister
this.removeControl(name);
// register
this.app.level.register(condition, control, { tag: DefaultTag, priority: defaultPriority, ...options });
this[__.private].addControlProperty(name, condition, control);
}
/**
* 移除(注销)指定名称的控件
* @param {string} name - 要移除的控件名
* @public
*
* 行为:
* - 调用 app.level.unregister 注销控件实例
* - 从私有映射中删除,并从 this 上移除对应属性
*/
removeControl(name) {
let _private = this[__.private];
let controlParam = _private.controlsMap.get(name);
if (!controlParam) {
return;
}
this.app.level.unregister(controlParam.control);
_private.controlsMap.delete(name);
delete this[name];
}
}
export { LevelControls }