guy
4 years ago
5 changed files with 2421 additions and 0 deletions
@ -0,0 +1,118 @@ |
|||||||
|
<html> |
||||||
|
<head> |
||||||
|
<meta charset="utf-8"> |
||||||
|
<title></title> |
||||||
|
<link rel="stylesheet" type="text/css" href="../dist/2.0/fineui.css"/> |
||||||
|
<script src="../dist/2.0/fineui.js"></script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
<div id="wrapper"></div> |
||||||
|
<script> |
||||||
|
// tab上下文环境测试 |
||||||
|
var Model = BI.inherit(Fix.Model, { |
||||||
|
state: function () { |
||||||
|
return { |
||||||
|
expand: false |
||||||
|
}; |
||||||
|
}, |
||||||
|
childContext: ["text"], |
||||||
|
|
||||||
|
computed: { |
||||||
|
text: function () { |
||||||
|
return this.model.expand ? "text-yes" : "text-not"; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
actions: { |
||||||
|
toggle: function () { |
||||||
|
this.model.expand = !this.model.expand; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
BI.model("demo.model", Model); |
||||||
|
var ChildModel = BI.inherit(Fix.Model, { |
||||||
|
context: ["text"] |
||||||
|
}); |
||||||
|
|
||||||
|
BI.model("demo.child_model", ChildModel); |
||||||
|
|
||||||
|
var Child = BI.inherit(BI.Widget, { |
||||||
|
setup: function () { |
||||||
|
var store = BI.useStore(function () { |
||||||
|
return BI.Models.getModel("demo.child_model"); |
||||||
|
}); |
||||||
|
return { |
||||||
|
render: function () { |
||||||
|
return { |
||||||
|
type: "bi.button", |
||||||
|
text: store.model.text |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.shortcut("demo.child", Child); |
||||||
|
|
||||||
|
var Widget = BI.inherit(BI.Widget, { |
||||||
|
props: { |
||||||
|
updateMode: "auto" |
||||||
|
}, |
||||||
|
setup: function () { |
||||||
|
var child; |
||||||
|
var store = BI.useStore(function () { |
||||||
|
return BI.Models.getModel("demo.model"); |
||||||
|
}); |
||||||
|
setInterval(function () { |
||||||
|
store.toggle(); |
||||||
|
}, 1000); |
||||||
|
BI.watch("text", function () { |
||||||
|
// child.reset(); |
||||||
|
}); |
||||||
|
return function () { |
||||||
|
return { |
||||||
|
type: "bi.vertical", |
||||||
|
vgap: 20, |
||||||
|
items: [{ |
||||||
|
type: "demo.child", |
||||||
|
ref: function (_ref) { |
||||||
|
child = _ref; |
||||||
|
} |
||||||
|
}, { |
||||||
|
type: "bi.combo", |
||||||
|
el: { |
||||||
|
type: "bi.button", |
||||||
|
text: "点击" |
||||||
|
}, |
||||||
|
popup: { |
||||||
|
el: { |
||||||
|
type: "bi.tab", |
||||||
|
height: 100, |
||||||
|
showIndex: 0, |
||||||
|
cardCreator: function () { |
||||||
|
return { |
||||||
|
type: "demo.child" |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}] |
||||||
|
}; |
||||||
|
}; |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.shortcut("demo.parent", Widget); |
||||||
|
BI.createWidget({ |
||||||
|
type: "bi.absolute", |
||||||
|
items: [{ |
||||||
|
el: { |
||||||
|
type: "demo.parent" |
||||||
|
}, |
||||||
|
top: 100, |
||||||
|
left: 100 |
||||||
|
}], |
||||||
|
element: "#wrapper" |
||||||
|
}); |
||||||
|
</script> |
||||||
|
</body> |
||||||
|
</html> |
@ -0,0 +1,153 @@ |
|||||||
|
/** |
||||||
|
* Created by GUY on 2015/6/26. |
||||||
|
*/ |
||||||
|
|
||||||
|
BI.Tab = BI.inherit(BI.Widget, { |
||||||
|
_defaultConfig: function () { |
||||||
|
return BI.extend(BI.Tab.superclass._defaultConfig.apply(this, arguments), { |
||||||
|
baseCls: "bi-tab", |
||||||
|
direction: "top", // top, bottom, left, right, custom
|
||||||
|
single: false, // 是不是单页面
|
||||||
|
logic: { |
||||||
|
dynamic: false |
||||||
|
}, |
||||||
|
showIndex: false, |
||||||
|
tab: false, |
||||||
|
cardCreator: function (v) { |
||||||
|
return BI.createWidget(); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
render: function () { |
||||||
|
var self = this, o = this.options; |
||||||
|
if (BI.isObject(o.tab)) { |
||||||
|
this.tab = BI.createWidget(this.options.tab, {type: "bi.button_group"}); |
||||||
|
this.tab.on(BI.Controller.EVENT_CHANGE, function (type, value, obj) { |
||||||
|
self.fireEvent(BI.Controller.EVENT_CHANGE, arguments); |
||||||
|
}); |
||||||
|
} |
||||||
|
this.cardMap = {}; |
||||||
|
this.layout = BI.createWidget({ |
||||||
|
type: "bi.card" |
||||||
|
}); |
||||||
|
|
||||||
|
BI.createWidget(BI.extend({ |
||||||
|
element: this |
||||||
|
}, BI.LogicFactory.createLogic(BI.LogicFactory.createLogicTypeByDirection(o.direction), BI.extend({}, o.logic, { |
||||||
|
items: BI.LogicFactory.createLogicItemsByDirection(o.direction, this.tab, this.layout) |
||||||
|
})))); |
||||||
|
|
||||||
|
var listener = new BI.ShowListener({ |
||||||
|
eventObj: this.tab, |
||||||
|
cardLayout: this.layout, |
||||||
|
cardCreator: function (v) { |
||||||
|
var card = o.cardCreator.apply(self, arguments); |
||||||
|
self.cardMap[v] = card; |
||||||
|
return card; |
||||||
|
}, |
||||||
|
afterCardShow: function (v) { |
||||||
|
self._deleteOtherCards(v); |
||||||
|
self.curr = v; |
||||||
|
} |
||||||
|
}); |
||||||
|
listener.on(BI.ShowListener.EVENT_CHANGE, function (value) { |
||||||
|
self.fireEvent(BI.Tab.EVENT_CHANGE, value, self); |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
_deleteOtherCards: function (currCardName) { |
||||||
|
var self = this, o = this.options; |
||||||
|
if (o.single === true) { |
||||||
|
BI.each(this.cardMap, function (name, card) { |
||||||
|
if (name !== (currCardName + "")) { |
||||||
|
self.layout.deleteCardByName(name); |
||||||
|
delete self.cardMap[name]; |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_assertCard: function (v) { |
||||||
|
if (!this.layout.isCardExisted(v)) { |
||||||
|
var card = this.options.cardCreator(v); |
||||||
|
this.cardMap[v] = card; |
||||||
|
this.layout.addCardByName(v, card); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
created: function () { |
||||||
|
var o = this.options; |
||||||
|
if (o.showIndex !== false) { |
||||||
|
this.setSelect(o.showIndex); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
setSelect: function (v) { |
||||||
|
this.tab && this.tab.setValue(v); |
||||||
|
this._assertCard(v); |
||||||
|
this.layout.showCardByName(v); |
||||||
|
this._deleteOtherCards(v); |
||||||
|
if (this.curr !== v) { |
||||||
|
this.curr = v; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
removeTab: function (cardname) { |
||||||
|
var self = this, o = this.options; |
||||||
|
BI.any(this.cardMap, function (name, card) { |
||||||
|
if (BI.isEqual(name, (cardname + ""))) { |
||||||
|
self.layout.deleteCardByName(name); |
||||||
|
delete self.cardMap[name]; |
||||||
|
return true; |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
getSelect: function () { |
||||||
|
return this.curr; |
||||||
|
}, |
||||||
|
|
||||||
|
getSelectedTab: function () { |
||||||
|
return this.layout.getShowingCard(); |
||||||
|
}, |
||||||
|
|
||||||
|
getTab: function (v) { |
||||||
|
this._assertCard(v); |
||||||
|
return this.layout.getCardByName(v); |
||||||
|
}, |
||||||
|
|
||||||
|
setValue: function (v) { |
||||||
|
var card = this.layout.getShowingCard(); |
||||||
|
if (card) { |
||||||
|
card.setValue(v); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
getValue: function () { |
||||||
|
var card = this.layout.getShowingCard(); |
||||||
|
if (card) { |
||||||
|
return card.getValue(); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
populate: function () { |
||||||
|
var card = this.layout.getShowingCard(); |
||||||
|
if (card) { |
||||||
|
return card.populate && card.populate.apply(card, arguments); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
empty: function () { |
||||||
|
this.layout.deleteAllCard(); |
||||||
|
this.cardMap = {}; |
||||||
|
}, |
||||||
|
|
||||||
|
destroy: function () { |
||||||
|
this.cardMap = {}; |
||||||
|
BI.Tab.superclass.destroy.apply(this, arguments); |
||||||
|
} |
||||||
|
}); |
||||||
|
BI.Tab.EVENT_CHANGE = "EVENT_CHANGE"; |
||||||
|
|
||||||
|
BI.shortcut("bi.tab", BI.Tab); |
@ -0,0 +1,92 @@ |
|||||||
|
(function () { |
||||||
|
var kv = {}; |
||||||
|
BI.shortcut = BI.component = BI.shortcut || function (xtype, cls) { |
||||||
|
if (kv[xtype] != null) { |
||||||
|
_global.console && console.error("shortcut:[" + xtype + "] has been registed"); |
||||||
|
} |
||||||
|
if (cls) { |
||||||
|
cls["xtype"] = xtype; |
||||||
|
} |
||||||
|
kv[xtype] = cls; |
||||||
|
}; |
||||||
|
|
||||||
|
// 根据配置属性生成widget
|
||||||
|
var createWidget = function (config, context, lazy) { |
||||||
|
var cls = kv[config.type]; |
||||||
|
|
||||||
|
if (!cls) { |
||||||
|
throw new Error("组件" + config.type + "未定义"); |
||||||
|
} |
||||||
|
var pushed = false; |
||||||
|
if (context) { |
||||||
|
pushed = true; |
||||||
|
BI.Widget.pushContext(context); |
||||||
|
} |
||||||
|
var widget = new cls(); |
||||||
|
widget._initProps(config); |
||||||
|
widget._constructed(); |
||||||
|
widget._initRoot(); |
||||||
|
// if (!lazy || config.element || config.root) {
|
||||||
|
widget._lazyConstructor(); |
||||||
|
// }
|
||||||
|
pushed && BI.Widget.popContext(); |
||||||
|
return widget; |
||||||
|
}; |
||||||
|
|
||||||
|
BI.createWidget = BI.createWidget || function (item, options, context, lazy) { |
||||||
|
// 先把准备环境准备好
|
||||||
|
BI.init(); |
||||||
|
var el, w; |
||||||
|
item || (item = {}); |
||||||
|
if (BI.isWidget(options)) { |
||||||
|
context = options; |
||||||
|
options = {}; |
||||||
|
} else { |
||||||
|
options || (options = {}); |
||||||
|
} |
||||||
|
if (BI.isEmpty(item) && BI.isEmpty(options)) { |
||||||
|
return BI.createWidget({ |
||||||
|
type: "bi.layout" |
||||||
|
}); |
||||||
|
} |
||||||
|
if (BI.isWidget(item)) { |
||||||
|
return item; |
||||||
|
} |
||||||
|
if (item.type || options.type) { |
||||||
|
el = BI.extend({}, options, item); |
||||||
|
w = BI.Plugin.getWidget(el.type, el); |
||||||
|
w.listeners = (w.listeners || []).concat([{ |
||||||
|
eventName: BI.Events.MOUNT, |
||||||
|
action: function () { |
||||||
|
BI.Plugin.getObject(el.type, this); |
||||||
|
} |
||||||
|
}]); |
||||||
|
return w.type === el.type ? createWidget(w, context, lazy) : BI.createWidget(BI.extend({/**important**/}, el, {type: w.type}), options, context, lazy); |
||||||
|
} |
||||||
|
if (item.el && (item.el.type || options.type)) { |
||||||
|
el = BI.extend({}, options, item.el); |
||||||
|
w = BI.Plugin.getWidget(el.type, el); |
||||||
|
w.listeners = (w.listeners || []).concat([{ |
||||||
|
eventName: BI.Events.MOUNT, |
||||||
|
action: function () { |
||||||
|
BI.Plugin.getObject(el.type, this); |
||||||
|
} |
||||||
|
}]); |
||||||
|
return w.type === el.type ? createWidget(w, context, lazy) : BI.createWidget(BI.extend({/**important**/}, el, {type: w.type}), options, context, lazy); |
||||||
|
} |
||||||
|
if (BI.isWidget(item.el)) { |
||||||
|
return item.el; |
||||||
|
} |
||||||
|
throw new Error("无法根据item创建组件"); |
||||||
|
}; |
||||||
|
|
||||||
|
BI._lazyCreateWidget = BI._lazyCreateWidget || function (item, options, context) { |
||||||
|
return BI.createWidget(item, options, context, true); |
||||||
|
}; |
||||||
|
|
||||||
|
BI.createElement = BI.createElement || function () { |
||||||
|
var widget = BI.createWidget.apply(this, arguments); |
||||||
|
return widget.element; |
||||||
|
}; |
||||||
|
|
||||||
|
})(); |
@ -0,0 +1,750 @@ |
|||||||
|
/** |
||||||
|
* Widget超类 |
||||||
|
* @class BI.Widget |
||||||
|
* @extends BI.OB |
||||||
|
* |
||||||
|
* @cfg {JSON} options 配置属性 |
||||||
|
*/ |
||||||
|
|
||||||
|
!(function () { |
||||||
|
function callLifeHook (self, life) { |
||||||
|
var hook = self.options[life] || self[life]; |
||||||
|
if (hook) { |
||||||
|
var hooks = BI.isArray(hook) ? hook : [hook]; |
||||||
|
BI.each(hooks, function (i, hook) { |
||||||
|
hook.call(self); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
BI.Widget = BI.Widget || BI.inherit(BI.OB, { |
||||||
|
_defaultConfig: function () { |
||||||
|
return BI.extend(BI.Widget.superclass._defaultConfig.apply(this), { |
||||||
|
root: false, |
||||||
|
tagName: "div", |
||||||
|
attributes: null, |
||||||
|
data: null, |
||||||
|
|
||||||
|
tag: null, |
||||||
|
disabled: false, |
||||||
|
invisible: false, |
||||||
|
invalid: false, |
||||||
|
baseCls: "", |
||||||
|
extraCls: "", |
||||||
|
cls: "", |
||||||
|
css: null, |
||||||
|
updateMode: "manual" // manual / auto
|
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
_constructor: function () { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
// 覆盖父类的_constructor方法,widget不走ob的生命周期
|
||||||
|
_constructed: function () { |
||||||
|
if (this.setup) { |
||||||
|
pushTarget(this); |
||||||
|
this.service = this.setup(this.options); |
||||||
|
this.render = BI.isPlainObject(this.service) ? this.service.render : this.service; |
||||||
|
popTarget(); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_lazyConstructor: function () { |
||||||
|
if (!this.__constructed) { |
||||||
|
this.__constructed = true; |
||||||
|
this._init(); |
||||||
|
this._initRef(); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
// 生命周期函数
|
||||||
|
beforeInit: null, |
||||||
|
|
||||||
|
beforeRender: null, |
||||||
|
|
||||||
|
beforeCreate: null, |
||||||
|
|
||||||
|
created: null, |
||||||
|
|
||||||
|
render: null, |
||||||
|
|
||||||
|
beforeMount: null, |
||||||
|
|
||||||
|
mounted: null, |
||||||
|
|
||||||
|
shouldUpdate: null, |
||||||
|
|
||||||
|
update: null, |
||||||
|
|
||||||
|
beforeUpdate: null, |
||||||
|
|
||||||
|
updated: null, |
||||||
|
|
||||||
|
beforeDestroy: null, |
||||||
|
|
||||||
|
destroyed: null, |
||||||
|
|
||||||
|
_init: function () { |
||||||
|
BI.Widget.superclass._init.apply(this, arguments); |
||||||
|
this._initElementWidth(); |
||||||
|
this._initElementHeight(); |
||||||
|
this._initVisual(); |
||||||
|
this._initState(); |
||||||
|
this._initRender(); |
||||||
|
}, |
||||||
|
|
||||||
|
_initRender: function () { |
||||||
|
var self = this; |
||||||
|
|
||||||
|
function render () { |
||||||
|
if (self.options.beforeRender || self.beforeRender) { |
||||||
|
(self.options.beforeRender || self.beforeRender).call(self, BI.bind(self._render, self)); |
||||||
|
} else { |
||||||
|
self._render(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (this.options.beforeInit || this.beforeInit) { |
||||||
|
this.__asking = true; |
||||||
|
(this.options.beforeInit || this.beforeInit).call(this, render); |
||||||
|
if (this.__asking === true) { |
||||||
|
this.__async = true; |
||||||
|
} |
||||||
|
} else { |
||||||
|
render(); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_render: function () { |
||||||
|
this.__asking = false; |
||||||
|
callLifeHook(this, "beforeCreate"); |
||||||
|
this._initElement(); |
||||||
|
this._initEffects(); |
||||||
|
callLifeHook(this, "created"); |
||||||
|
}, |
||||||
|
|
||||||
|
_initCurrent: function () { |
||||||
|
var o = this.options; |
||||||
|
if (o._baseCls || o.baseCls || o.extraCls || o.cls) { |
||||||
|
this.element.addClass((o._baseCls || "") + " " + (o.baseCls || "") + " " + (o.extraCls || "") + " " + (o.cls || "")); |
||||||
|
} |
||||||
|
if (o.attributes) { |
||||||
|
this.element.attr(o.attributes); |
||||||
|
} |
||||||
|
if (o.data) { |
||||||
|
this.element.data(o.data); |
||||||
|
} |
||||||
|
if (o.css) { |
||||||
|
this.element.css(o.css); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* 初始化根节点 |
||||||
|
* @private |
||||||
|
*/ |
||||||
|
_initRoot: function () { |
||||||
|
var o = this.options; |
||||||
|
this.widgetName = o.widgetName || BI.uniqueId("widget"); |
||||||
|
this._isRoot = o.root; |
||||||
|
this._children = {}; |
||||||
|
if (BI.isWidget(o.element)) { |
||||||
|
this.element = this.options.element.element; |
||||||
|
if (o.element instanceof BI.Widget) { |
||||||
|
this._parent = o.element; |
||||||
|
this._parent.addWidget(this.widgetName, this); |
||||||
|
} else { |
||||||
|
this._isRoot = true; |
||||||
|
} |
||||||
|
} else if (o.element) { |
||||||
|
// if (o.root !== true) {
|
||||||
|
// throw new Error("root is a required property");
|
||||||
|
// }
|
||||||
|
this.element = BI.Widget._renderEngine.createElement(this); |
||||||
|
this._isRoot = true; |
||||||
|
} else { |
||||||
|
this.element = BI.Widget._renderEngine.createElement(this); |
||||||
|
} |
||||||
|
this.element._isWidget = true; |
||||||
|
this._initCurrent(); |
||||||
|
}, |
||||||
|
|
||||||
|
_initElementWidth: function () { |
||||||
|
var o = this.options; |
||||||
|
if (BI.isWidthOrHeight(o.width)) { |
||||||
|
this.element.css("width", BI.isNumber(o.width) ? o.width / BI.pixRatio + BI.pixUnit : o.width); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_initElementHeight: function () { |
||||||
|
var o = this.options; |
||||||
|
if (BI.isWidthOrHeight(o.height)) { |
||||||
|
this.element.css("height", BI.isNumber(o.height) ? o.height / BI.pixRatio + BI.pixUnit : o.height); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_initVisual: function () { |
||||||
|
var o = this.options; |
||||||
|
if (o.invisible) { |
||||||
|
// 用display属性做显示和隐藏,否则jquery会在显示时将display设为block会覆盖掉display:flex属性
|
||||||
|
this.element.css("display", "none"); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_initEffects: function () { |
||||||
|
var o = this.options; |
||||||
|
if (o.disabled || o.invalid) { |
||||||
|
if (this.options.disabled) { |
||||||
|
this.setEnable(false); |
||||||
|
} |
||||||
|
if (this.options.invalid) { |
||||||
|
this.setValid(false); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_initState: function () { |
||||||
|
this._isMounted = false; |
||||||
|
}, |
||||||
|
|
||||||
|
_initElement: function () { |
||||||
|
var self = this; |
||||||
|
var render = BI.isFunction(this.options.render) ? this.options.render : this.render; |
||||||
|
var els = render && render.call(this); |
||||||
|
if (BI.isPlainObject(els)) { |
||||||
|
els = [els]; |
||||||
|
} |
||||||
|
if (BI.isArray(els)) { |
||||||
|
BI.each(els, function (i, el) { |
||||||
|
if (el) { |
||||||
|
BI._lazyCreateWidget(el, { |
||||||
|
element: self |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
// if (this._isRoot === true || !(this instanceof BI.Layout)) {
|
||||||
|
this._mount(); |
||||||
|
// }
|
||||||
|
}, |
||||||
|
|
||||||
|
_setParent: function (parent) { |
||||||
|
this._parent = parent; |
||||||
|
}, |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* @param force 是否强制挂载子节点 |
||||||
|
* @param deep 子节点是否也是按照当前force处理 |
||||||
|
* @param lifeHook 生命周期钩子触不触发,默认触发 |
||||||
|
* @param predicate 递归每个widget的回调 |
||||||
|
* @returns {boolean} |
||||||
|
* @private |
||||||
|
*/ |
||||||
|
_mount: function (force, deep, lifeHook, predicate, layer) { |
||||||
|
var self = this; |
||||||
|
if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
layer = layer || 0; |
||||||
|
lifeHook !== false && callLifeHook(this, "beforeMount"); |
||||||
|
this._isMounted = true; |
||||||
|
for (var key in this._children) { |
||||||
|
var child = this._children[key]; |
||||||
|
!self.isEnabled() && child._setEnable(false); |
||||||
|
!self.isValid() && child._setValid(false); |
||||||
|
child._mount && child._mount(deep ? force : false, deep, lifeHook, predicate, layer + 1); |
||||||
|
} |
||||||
|
this._mountChildren && this._mountChildren(); |
||||||
|
if (layer === 0) { |
||||||
|
// mounted里面会执行scrollTo之类的方法,如果放宏任务里会闪
|
||||||
|
// setTimeout(function () {
|
||||||
|
self.__afterMount(lifeHook, predicate); |
||||||
|
// }, 0);
|
||||||
|
} |
||||||
|
return true; |
||||||
|
}, |
||||||
|
|
||||||
|
__afterMount: function (lifeHook, predicate) { |
||||||
|
if (this._isMounted) { |
||||||
|
for (var key in this._children) { |
||||||
|
var child = this._children[key]; |
||||||
|
child.__afterMount && child.__afterMount(lifeHook, predicate); |
||||||
|
} |
||||||
|
lifeHook !== false && callLifeHook(this, "mounted"); |
||||||
|
this.fireEvent(BI.Events.MOUNT); |
||||||
|
predicate && predicate(this); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
_mountChildren: null, |
||||||
|
|
||||||
|
_update: function (nextProps, shouldUpdate) { |
||||||
|
var o = this.options; |
||||||
|
callLifeHook(this, "beforeUpdate"); |
||||||
|
if (shouldUpdate) { |
||||||
|
var res = this.update && this.update(nextProps, shouldUpdate); |
||||||
|
} else if (BI.isNull(shouldUpdate)) { |
||||||
|
// 默认使用shallowCompare的方式进行更新
|
||||||
|
var nextChange = {}; |
||||||
|
BI.each(nextProps, function (key, value) { |
||||||
|
if (o[key] !== value) { |
||||||
|
nextChange[key] = value; |
||||||
|
} |
||||||
|
}); |
||||||
|
var res = this.update && BI.isNotEmptyObject(nextChange) && this.update(nextChange); |
||||||
|
} |
||||||
|
callLifeHook(this, "updated"); |
||||||
|
return res; |
||||||
|
}, |
||||||
|
|
||||||
|
isMounted: function () { |
||||||
|
return this._isMounted; |
||||||
|
}, |
||||||
|
|
||||||
|
setWidth: function (w) { |
||||||
|
this.options.width = w; |
||||||
|
this._initElementWidth(); |
||||||
|
}, |
||||||
|
|
||||||
|
setHeight: function (h) { |
||||||
|
this.options.height = h; |
||||||
|
this._initElementHeight(); |
||||||
|
}, |
||||||
|
|
||||||
|
_setEnable: function (enable) { |
||||||
|
if (enable === true) { |
||||||
|
this.options.disabled = false; |
||||||
|
} else if (enable === false) { |
||||||
|
this.options.disabled = true; |
||||||
|
} |
||||||
|
// 递归将所有子组件使能
|
||||||
|
BI.each(this._children, function (i, child) { |
||||||
|
!child._manualSetEnable && child._setEnable && child._setEnable(enable); |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
_setValid: function (valid) { |
||||||
|
if (valid === true) { |
||||||
|
this.options.invalid = false; |
||||||
|
} else if (valid === false) { |
||||||
|
this.options.invalid = true; |
||||||
|
} |
||||||
|
// 递归将所有子组件使有效
|
||||||
|
BI.each(this._children, function (i, child) { |
||||||
|
!child._manualSetValid && child._setValid && child._setValid(valid); |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
_setVisible: function (visible) { |
||||||
|
if (visible === true) { |
||||||
|
this.options.invisible = false; |
||||||
|
} else if (visible === false) { |
||||||
|
this.options.invisible = true; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
setEnable: function (enable) { |
||||||
|
this._manualSetEnable = true; |
||||||
|
this._setEnable(enable); |
||||||
|
if (enable === true) { |
||||||
|
this.element.removeClass("base-disabled disabled"); |
||||||
|
} else if (enable === false) { |
||||||
|
this.element.addClass("base-disabled disabled"); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
setVisible: function (visible) { |
||||||
|
this._setVisible(visible); |
||||||
|
if (visible === true) { |
||||||
|
// 用this.element.show()会把display属性改成block
|
||||||
|
this.element.css("display", ""); |
||||||
|
this._mount(); |
||||||
|
} else if (visible === false) { |
||||||
|
this.element.css("display", "none"); |
||||||
|
} |
||||||
|
this.fireEvent(BI.Events.VIEW, visible); |
||||||
|
}, |
||||||
|
|
||||||
|
setValid: function (valid) { |
||||||
|
this._manualSetValid = true; |
||||||
|
this._setValid(valid); |
||||||
|
if (valid === true) { |
||||||
|
this.element.removeClass("base-invalid invalid"); |
||||||
|
} else if (valid === false) { |
||||||
|
this.element.addClass("base-invalid invalid"); |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
doBehavior: function () { |
||||||
|
var args = arguments; |
||||||
|
// 递归将所有子组件使有效
|
||||||
|
BI.each(this._children, function (i, child) { |
||||||
|
child.doBehavior && child.doBehavior.apply(child, args); |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
getWidth: function () { |
||||||
|
return this.options.width; |
||||||
|
}, |
||||||
|
|
||||||
|
getHeight: function () { |
||||||
|
return this.options.height; |
||||||
|
}, |
||||||
|
|
||||||
|
isValid: function () { |
||||||
|
return !this.options.invalid; |
||||||
|
}, |
||||||
|
|
||||||
|
addWidget: function (name, widget) { |
||||||
|
var self = this; |
||||||
|
if (name instanceof BI.Widget) { |
||||||
|
widget = name; |
||||||
|
name = widget.getName(); |
||||||
|
} |
||||||
|
if (BI.isKey(name)) { |
||||||
|
name = name + ""; |
||||||
|
} |
||||||
|
name = name || widget.getName() || BI.uniqueId("widget"); |
||||||
|
if (this._children[name]) { |
||||||
|
throw new Error("name has already been existed"); |
||||||
|
} |
||||||
|
widget._setParent && widget._setParent(this); |
||||||
|
widget.on(BI.Events.DESTROY, function () { |
||||||
|
BI.remove(self._children, this); |
||||||
|
}); |
||||||
|
return (this._children[name] = widget); |
||||||
|
}, |
||||||
|
|
||||||
|
getWidgetByName: function (name) { |
||||||
|
if (!BI.isKey(name) || name === this.getName()) { |
||||||
|
return this; |
||||||
|
} |
||||||
|
name = name + ""; |
||||||
|
var widget = void 0, other = {}; |
||||||
|
BI.any(this._children, function (i, wi) { |
||||||
|
if (i === name) { |
||||||
|
widget = wi; |
||||||
|
return true; |
||||||
|
} |
||||||
|
other[i] = wi; |
||||||
|
}); |
||||||
|
if (!widget) { |
||||||
|
BI.any(other, function (i, wi) { |
||||||
|
return (widget = wi.getWidgetByName(i)); |
||||||
|
}); |
||||||
|
} |
||||||
|
return widget; |
||||||
|
}, |
||||||
|
|
||||||
|
removeWidget: function (nameOrWidget) { |
||||||
|
var self = this; |
||||||
|
if (BI.isWidget(nameOrWidget)) { |
||||||
|
BI.remove(this._children, nameOrWidget); |
||||||
|
} else { |
||||||
|
delete this._children[nameOrWidget]; |
||||||
|
} |
||||||
|
}, |
||||||
|
|
||||||
|
hasWidget: function (name) { |
||||||
|
return this._children[name] != null; |
||||||
|
}, |
||||||
|
|
||||||
|
getName: function () { |
||||||
|
return this.widgetName; |
||||||
|
}, |
||||||
|
|
||||||
|
setTag: function (tag) { |
||||||
|
this.options.tag = tag; |
||||||
|
}, |
||||||
|
|
||||||
|
getTag: function () { |
||||||
|
return this.options.tag; |
||||||
|
}, |
||||||
|
|
||||||
|
attr: function (key, value) { |
||||||
|
var self = this; |
||||||
|
if (BI.isPlainObject(key)) { |
||||||
|
BI.each(key, function (k, v) { |
||||||
|
self.attr(k, v); |
||||||
|
}); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (BI.isNotNull(value)) { |
||||||
|
return this.options[key] = value; |
||||||
|
} |
||||||
|
return this.options[key]; |
||||||
|
}, |
||||||
|
|
||||||
|
css: function (name, value) { |
||||||
|
return this.element.css(name, value); |
||||||
|
}, |
||||||
|
|
||||||
|
getText: function () { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setText: function (text) { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
getValue: function () { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
setValue: function (value) { |
||||||
|
|
||||||
|
}, |
||||||
|
|
||||||
|
isEnabled: function () { |
||||||
|
return !this.options.disabled; |
||||||
|
}, |
||||||
|
|
||||||
|
isVisible: function () { |
||||||
|
return !this.options.invisible; |
||||||
|
}, |
||||||
|
|
||||||
|
disable: function () { |
||||||
|
this.setEnable(false); |
||||||
|
}, |
||||||
|
|
||||||
|
enable: function () { |
||||||
|
this.setEnable(true); |
||||||
|
}, |
||||||
|
|
||||||
|
valid: function () { |
||||||
|
this.setValid(true); |
||||||
|
}, |
||||||
|
|
||||||
|
invalid: function () { |
||||||
|
this.setValid(false); |
||||||
|
}, |
||||||
|
|
||||||
|
invisible: function () { |
||||||
|
this.setVisible(false); |
||||||
|
}, |
||||||
|
|
||||||
|
visible: function () { |
||||||
|
this.setVisible(true); |
||||||
|
}, |
||||||
|
|
||||||
|
__d: function () { |
||||||
|
callLifeHook(this, "beforeDestroy"); |
||||||
|
this.beforeDestroy = null; |
||||||
|
BI.each(this._children, function (i, widget) { |
||||||
|
widget && widget._unMount && widget._unMount(); |
||||||
|
}); |
||||||
|
this._children = {}; |
||||||
|
this._parent = null; |
||||||
|
this._isMounted = false; |
||||||
|
callLifeHook(this, "destroyed"); |
||||||
|
this.destroyed = null; |
||||||
|
}, |
||||||
|
|
||||||
|
_unMount: function () { |
||||||
|
this.__d(); |
||||||
|
this.fireEvent(BI.Events.UNMOUNT); |
||||||
|
this.purgeListeners(); |
||||||
|
}, |
||||||
|
|
||||||
|
isolate: function () { |
||||||
|
if (this._parent) { |
||||||
|
this._parent.removeWidget(this); |
||||||
|
} |
||||||
|
BI.DOM.hang([this]); |
||||||
|
}, |
||||||
|
|
||||||
|
empty: function () { |
||||||
|
BI.each(this._children, function (i, widget) { |
||||||
|
widget && widget._unMount && widget._unMount(); |
||||||
|
}); |
||||||
|
this._children = {}; |
||||||
|
this.element.empty(); |
||||||
|
}, |
||||||
|
|
||||||
|
// 默认的populate方法就是干掉重来
|
||||||
|
reset: function () { |
||||||
|
this.purgeListeners(); |
||||||
|
this.empty(); |
||||||
|
this._initCurrent(); |
||||||
|
this._init(); |
||||||
|
this._initRef(); |
||||||
|
}, |
||||||
|
|
||||||
|
_destroy: function () { |
||||||
|
this.__d(); |
||||||
|
this.element.destroy(); |
||||||
|
this.purgeListeners(); |
||||||
|
}, |
||||||
|
|
||||||
|
destroy: function () { |
||||||
|
this.__d(); |
||||||
|
this.element.destroy(); |
||||||
|
this.fireEvent(BI.Events.UNMOUNT); |
||||||
|
this.fireEvent(BI.Events.DESTROY); |
||||||
|
this._purgeRef(); |
||||||
|
this.purgeListeners(); |
||||||
|
} |
||||||
|
}); |
||||||
|
var context = null, current = null; |
||||||
|
var contextStack = [], currentStack = []; |
||||||
|
|
||||||
|
BI.Widget.pushContext = function (_context) { |
||||||
|
if (context) contextStack.push(context); |
||||||
|
BI.Widget.context = context = _context; |
||||||
|
}; |
||||||
|
|
||||||
|
BI.Widget.popContext = function () { |
||||||
|
BI.Widget.context = context = contextStack.pop(); |
||||||
|
}; |
||||||
|
|
||||||
|
function pushTarget (_current) { |
||||||
|
if (current) currentStack.push(current); |
||||||
|
BI.Widget.current = current = _current; |
||||||
|
} |
||||||
|
|
||||||
|
function popTarget () { |
||||||
|
BI.Widget.current = current = currentStack.pop(); |
||||||
|
} |
||||||
|
|
||||||
|
BI.useStore = function (_store) { |
||||||
|
if (current && current.store) { |
||||||
|
return current.store; |
||||||
|
} |
||||||
|
if (current && current.$storeDelegate) { |
||||||
|
return current.$storeDelegate; |
||||||
|
} |
||||||
|
if (current) { |
||||||
|
var delegate = {}, origin; |
||||||
|
if (_global.Proxy) { |
||||||
|
var proxy = new Proxy(delegate, { |
||||||
|
get: function (target, key) { |
||||||
|
return Reflect.get(origin, key); |
||||||
|
}, |
||||||
|
set: function (target, key, value) { |
||||||
|
return Reflect.set(origin, key, value); |
||||||
|
} |
||||||
|
}); |
||||||
|
current._store = function () { |
||||||
|
origin = _store.apply(this, arguments); |
||||||
|
return origin; |
||||||
|
}; |
||||||
|
return current.$storeDelegate = proxy; |
||||||
|
} |
||||||
|
current._store = function () { |
||||||
|
var st = _store.apply(this, arguments); |
||||||
|
BI.extend(delegate, st); |
||||||
|
return st; |
||||||
|
}; |
||||||
|
return current.$storeDelegate = delegate; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
BI.watch = function (watch, handler) { |
||||||
|
if (BI.Widget.current) { |
||||||
|
BI.Widget.current.$watchDelayCallbacks || (BI.Widget.current.$watchDelayCallbacks = []); |
||||||
|
BI.Widget.current.$watchDelayCallbacks.push([watch, handler]); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
BI.onBeforeMount = function (beforeMount) { |
||||||
|
if (current) { |
||||||
|
if (!current.beforeMount) { |
||||||
|
current.beforeMount = []; |
||||||
|
} else if (!BI.isArray(current.beforeMount)) { |
||||||
|
current.beforeMount = [current.beforeMount]; |
||||||
|
} |
||||||
|
current.beforeMount.push(beforeMount); |
||||||
|
} |
||||||
|
}; |
||||||
|
BI.onMounted = function (mounted) { |
||||||
|
if (current) { |
||||||
|
if (!current.mounted) { |
||||||
|
current.mounted = []; |
||||||
|
} else if (!BI.isArray(current.mounted)) { |
||||||
|
current.mounted = [current.mounted]; |
||||||
|
} |
||||||
|
current.mounted.push(mounted); |
||||||
|
} |
||||||
|
}; |
||||||
|
BI.onBeforeUnmount = function (beforeDestroy) { |
||||||
|
if (current) { |
||||||
|
if (!current.beforeDestroy) { |
||||||
|
current.beforeDestroy = []; |
||||||
|
} else if (!BI.isArray(current.beforeDestroy)) { |
||||||
|
current.beforeDestroy = [current.beforeDestroy]; |
||||||
|
} |
||||||
|
current.beforeDestroy.push(beforeDestroy); |
||||||
|
} |
||||||
|
}; |
||||||
|
BI.onUnmounted = function (destroyed) { |
||||||
|
if (current) { |
||||||
|
if (!current.destroyed) { |
||||||
|
current.destroyed = []; |
||||||
|
} else if (!BI.isArray(current.destroyed)) { |
||||||
|
current.destroyed = [current.destroyed]; |
||||||
|
} |
||||||
|
current.destroyed.push(destroyed); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
BI.Widget.registerRenderEngine = function (engine) { |
||||||
|
BI.Widget._renderEngine = engine; |
||||||
|
}; |
||||||
|
BI.Widget.registerRenderEngine({ |
||||||
|
createElement: function (widget) { |
||||||
|
if (BI.isWidget(widget)) { |
||||||
|
var o = widget.options; |
||||||
|
if (o.element) { |
||||||
|
return BI.$(o.element); |
||||||
|
} |
||||||
|
if (o.tagName) { |
||||||
|
return BI.$(document.createElement(o.tagName)); |
||||||
|
} |
||||||
|
return BI.$(document.createDocumentFragment()); |
||||||
|
} |
||||||
|
return BI.$(widget); |
||||||
|
}, |
||||||
|
createFragment: function () { |
||||||
|
return document.createDocumentFragment(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
BI.mount = function (widget, container, predicate, hydrate) { |
||||||
|
if (hydrate === true) { |
||||||
|
// 将widget的element元素都挂载好,并建立相互关系
|
||||||
|
widget.element.data("__widgets", [widget]); |
||||||
|
var res = widget._mount(true, false, false, function (w) { |
||||||
|
BI.each(w._children, function (i, child) { |
||||||
|
var ws = child.element.data("__widgets"); |
||||||
|
if (!ws) { |
||||||
|
ws = []; |
||||||
|
} |
||||||
|
ws.push(child); |
||||||
|
child.element.data("__widgets", ws); |
||||||
|
}); |
||||||
|
predicate && predicate.apply(this, arguments); |
||||||
|
}); |
||||||
|
// 将新的dom树属性(事件等)patch到已存在的dom上
|
||||||
|
var c = BI.Widget._renderEngine.createElement; |
||||||
|
BI.DOM.patchProps(widget.element, c(c(container).children()[0])); |
||||||
|
|
||||||
|
var triggerLifeHook = function (w) { |
||||||
|
w.beforeMount && w.beforeMount(); |
||||||
|
w.mounted && w.mounted(); |
||||||
|
BI.each(w._children, function (i, child) { |
||||||
|
triggerLifeHook(child); |
||||||
|
}); |
||||||
|
}; |
||||||
|
// 最后触发组件树生命周期函数
|
||||||
|
triggerLifeHook(widget); |
||||||
|
return res; |
||||||
|
} |
||||||
|
if (container) { |
||||||
|
BI.Widget._renderEngine.createElement(container).append(widget.element); |
||||||
|
} |
||||||
|
return widget._mount(true, false, false, predicate); |
||||||
|
}; |
||||||
|
})(); |
Loading…
Reference in new issue