fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

217 lines
6.1 KiB

import { isFunction, isArray, isObject, isArguments, reduce, bind } from "./2.base";
function obExtend() {
let target = arguments[0] || {}, length = arguments.length, i = 1, name, copy;
for (; i < length; i++) {
// Only deal with non-null/undefined values
const options = arguments[i];
if (options !== null) {
// Extend the base object
for (name in options) {
copy = options[name];
// Prevent never-ending loop
if (target === copy) {
continue;
}
if (copy !== undefined) {
target[name] = copy;
}
}
}
}
return target;
}
export class OB {
// props = {};
// init = null;
// destroyed = null;
constructor(config) {
this._constructor(config);
}
_constructor(config) {
this._initProps(config);
this._init();
this._initRef();
}
_defaultConfig(config) {
return {};
}
_initProps(config) {
let props = this.props;
if (isFunction(this.props)) {
props = this.props(config);
}
const defaultProps = obExtend(this._defaultConfig(config), props);
const modifiedDefaultProps = (config && config.type && OB.configFunctions[config.type + ".props"]) ? reduce(OB.configFunctions[config.type + ".props"], function (value, conf, index) {
return obExtend(conf, value.fn(defaultProps, config, value.opt));
}, {}) : null;
this.options = obExtend(defaultProps, modifiedDefaultProps, config);
}
_init() {
this._initListeners();
this.init && this.init();
}
_initListeners() {
if (this.options.listeners !== null) {
BI._.each(this.options.listeners, (lis, eventName) => {
if (isFunction(lis)) {
this.on(eventName, lis);
return;
}
if (isArray(lis)) {
BI._.each(lis, (l) => {
this.on(eventName, l);
});
return;
}
(lis.target ? lis.target : this)[lis.once ? "once" : "on"](lis.eventName, bind(lis.action, this));
});
delete this.options.listeners;
}
}
// 获得一个当前对象的引用
_initRef() {
const o = this.options;
if (o.__ref) {
isFunction(o.__ref) ? o.__ref.call(this, this) : o.__ref.current = this;
}
if (o.ref) {
isFunction(o.ref) ? o.ref.call(this, this) : o.ref.current = this;
}
}
// 释放当前对象
_purgeRef() {
const o = this.options;
if (o.__ref) {
isFunction(o.__ref) ? o.__ref.call(null, null) : o.__ref.current = null;
o.__ref = null;
}
if (o.ref) {
isFunction(o.ref) ? o.ref.call(null, null) : o.ref.current = null;
o.ref = null;
}
}
_getEvents() {
if (!isObject(this.events)) {
this.events = {};
}
return this.events;
}
/**
* 给观察者绑定一个事件
* @param {String} eventName 事件的名字
* @param {Function} fn 事件对应的执行函数
*/
on(eventName, fn) {
eventName = eventName.toLowerCase();
let fns = this._getEvents()[eventName];
if (!isArray(fns)) {
fns = [];
this._getEvents()[eventName] = fns;
}
fns.push(fn);
return () => this.un(eventName, fn);
}
/**
* 给观察者绑定一个只执行一次的事件
* @param {String} eventName 事件的名字
* @param {Function} fn 事件对应的执行函数
*/
once(eventName, fn) {
const proxy = () => {
fn.apply(this, arguments);
this.un(eventName, proxy);
};
this.on(eventName, proxy);
}
/**
* 解除观察者绑定的指定事件
* @param {String} eventName 要解除绑定事件的名字
* @param {Function} fn 事件对应的执行函数,该参数是可选的,没有该参数时,将解除绑定所有同名字的事件
*/
un(eventName, fn) {
eventName = eventName.toLowerCase();
/* alex:如果fn是null,就是把eventName上面所有方法都un掉*/
if (fn === null) {
delete this._getEvents()[eventName];
} else {
const fns = this._getEvents()[eventName];
if (isArray(fns)) {
const newFns = [];
BI._.each(fns, function (ifn) {
if (ifn !== fn) {
newFns.push(ifn);
}
});
this._getEvents()[eventName] = newFns;
}
}
}
/**
* 清除观察者的所有事件绑定
*/
purgeListeners() {
/* alex:清空events*/
this.events = {};
}
/**
* 触发绑定过的事件
*
* @param {String} eventName 要触发的事件的名字
* @returns {Boolean} 如果事件函数返回false,则返回false并中断其他同名事件的执行,否则执行所有的同名事件并返回true
*/
fireEvent() {
const eventName = arguments[0].toLowerCase();
const fns = this._getEvents()[eventName];
if (isArray(fns)) {
if (isArguments(arguments[1])) {
for (let i = 0; i < fns.length; i++) {
if (fns[i].apply(this, arguments[1]) === false) {
return false;
}
}
} else {
const args = Array.prototype.slice.call(arguments, 1);
for (let i = 0; i < fns.length; i++) {
if (fns[i].apply(this, args) === false) {
return false;
}
}
}
}
return true;
}
destroy() {
this.destroyed && this.destroyed();
this._purgeRef();
this.purgeListeners();
}
}