diff --git a/demo/js/case/tree/demo.branch_tree.js b/demo/js/case/tree/demo.branch_tree.js index 76d1ad7ba..91b9bd69f 100644 --- a/demo/js/case/tree/demo.branch_tree.js +++ b/demo/js/case/tree/demo.branch_tree.js @@ -72,7 +72,7 @@ Demo.Func = BI.inherit(BI.Widget, { var tree = BI.createWidget({ type: "bi.branch_tree", el: { - type: "bi.button_group" + type: "bi.virtual_group" }, items: [{ text: "且", @@ -159,8 +159,8 @@ Demo.Func = BI.inherit(BI.Widget, { type: "bi.label", height: 30, textAlign: "left", - text: "这里是一段文字" + BI.UUID(), - value: "这里是一段文字" + BI.UUID() + text: "这里是一段文字" , + value: "这里是一段文字" }, { text: "且", value: "且3", diff --git a/demo/js/config/core.js b/demo/js/config/core.js index 6d83a0f9b..757617793 100644 --- a/demo/js/config/core.js +++ b/demo/js/config/core.js @@ -91,8 +91,8 @@ Demo.CORE_CONFIG = [{ value: "demo.button_tree" }, { pId: 102, - text: "bi.button_map", - value: "demo.button_map" + text: "bi.virtual_group", + value: "demo.virtual_group" }, { pId: 102, id: 10201, diff --git a/demo/js/core/abstract/demo.button_map.js b/demo/js/core/abstract/demo.button_map.js deleted file mode 100644 index f3e76f2f5..000000000 --- a/demo/js/core/abstract/demo.button_map.js +++ /dev/null @@ -1,26 +0,0 @@ -Demo.Func = BI.inherit(BI.Widget, { - props: { - baseCls: "demo-func" - }, - render: function () { - return { - type: "bi.button_map", - chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, - layouts: [{ - type: "bi.vertical" - }, { - type: "bi.center_adapt", - }], - items: [{ - type: "bi.label", - text: "0", - value: 0 - }, { - type: "bi.button", - text: "1", - value: 1 - }] - } - } -}); -$.shortcut("demo.button_map", Demo.Func); \ No newline at end of file diff --git a/demo/js/core/abstract/demo.virtual_group.js b/demo/js/core/abstract/demo.virtual_group.js new file mode 100644 index 000000000..0c746cffa --- /dev/null +++ b/demo/js/core/abstract/demo.virtual_group.js @@ -0,0 +1,74 @@ +Demo.Func = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-func" + }, + + _createItems: function () { + var items = BI.makeArray(100, { + type: "demo.virtual_group_item" + }); + items[0].value = BI.UUID(); + return items; + }, + + render: function () { + var self = this; + return { + type: "bi.vertical", + vgap: 20, + items: [{ + type: "bi.virtual_group", + width: 200, + height: 300, + ref: function () { + self.buttonMap = this; + }, + chooseType: BI.ButtonGroup.CHOOSE_TYPE_MULTI, + layouts: [{ + type: "bi.vertical" + }, { + type: "bi.center_adapt", + }], + items: this._createItems() + }, { + type: "bi.button", + text: "点击刷新", + handler: function () { + self.buttonMap.populate(self._createItems()); + } + }] + + } + } +}); +$.shortcut("demo.virtual_group", Demo.Func); + +Demo.Item = BI.inherit(BI.Widget, { + props: { + baseCls: "demo-item", + height: 30 + }, + + render: function () { + var self = this; + return { + type: "bi.label", + ref: function () { + self.label = this; + }, + height: this.options.height, + text: "这是一个测试项" + BI.UUID() + } + }, + + update: function (item) { + this.label.setText(item.value); + console.log("更新了一项"); + return true; + }, + + created: function () { + console.log("创建了一项"); + } +}); +$.shortcut("demo.virtual_group_item", Demo.Item); \ No newline at end of file diff --git a/dist/base.js b/dist/base.js index 345bc1725..9acaf99f9 100644 --- a/dist/base.js +++ b/dist/base.js @@ -1129,11 +1129,12 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { }, populate: function (items) { - this.options.items = items || []; + items = items || []; + this.options.items = items; this.empty(); this.buttons = this._btnsCreator.apply(this, arguments); - var items = this._packageItems(items, this._packageBtns(this.buttons)); + items = this._packageItems(items, this._packageBtns(this.buttons)); this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); }, @@ -1454,120 +1455,6 @@ BI.ButtonTree = BI.inherit(BI.ButtonGroup, { BI.ButtonTree.EVENT_CHANGE = "EVENT_CHANGE"; $.shortcut("bi.button_tree", BI.ButtonTree);/** - * value作为key值缓存button, 不支持顺序读写 - * 适合用于频繁增删的一组button - * Created by GUY on 2015/8/10. - * @class BI.ButtonMap - * @extends BI.ButtonTree - */ - -BI.ButtonMap = BI.inherit(BI.ButtonTree, { - _defaultConfig: function () { - return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-map" - }) - }, - - _init: function () { - BI.ButtonMap.superclass._init.apply(this, arguments); - }, - - _createBtns: function (items) { - var self = this, o = this.options; - var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); - var keys = BI.map(items, function (i, item) { - item = BI.stripEL(item); - if (!(BI.isKey(item.id) || BI.isKey(item.value))) { - throw new Error("item必须包含id或value属性"); - } - return item.id || item.value; - }); - return BI.object(keys, buttons); - }, - - setValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); - }, - - setNotSelectedValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); - }, - - populate: function (items) { - var self = this; - var args = [].slice.call(arguments); - var linkHashMap = new BI.LinkHashMap(); - var val = function (item) { - return item.id || item.value; - }; - if (!this.buttons) { - this.buttons = {}; - } - //所有已存在的和新添加的 - var willCreated = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - if (self.buttons[val(item)]) { - var ob = self.buttons[val(item)]; - args[0] = item.items; - args[2] = item; - ob.populate && ob.populate.apply(ob, args); - } else { - willCreated.push(item); - } - }); - //创建新元素 - args[0] = willCreated; - var newBtns = this._btnsCreator.apply(this, args); - - //整理 - var array = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - var button = self.buttons[val(item)] || newBtns[val(item)]; - linkHashMap.add(val(item), button); - array.push(button); - }); - this.buttons = linkHashMap.map; - - BI.DOM.hang(this.buttons); - this.empty(); - - var packages = this._packageItems(items, this._packageBtns(array)); - BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); - }, - - getIndexByValue: function (value) { - throw new Error("不能使用getIndexByValue方法"); - } -}); -BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; - -$.shortcut("bi.button_map", BI.ButtonMap);/** * guy * 异步树 * @class BI.TreeView @@ -3665,7 +3552,75 @@ BI.ComboGroup = BI.inherit(BI.Widget, { }); BI.ComboGroup.EVENT_CHANGE = "EVENT_CHANGE"; -$.shortcut("bi.combo_group", BI.ComboGroup);/** +$.shortcut("bi.combo_group", BI.ComboGroup);BI.VirtualGroup = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.VirtualGroup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-virtual-group", + items: [], + layouts: [{ + type: "bi.center", + hgap: 0, + vgap: 0 + }] + }) + }, + + render: function () { + this.populate(this.options.items); + }, + + _createBtns: function (items) { + var o = this.options; + return BI.createItems(items, { + type: "bi.text_button" + }); + }, + + _packageBtns: function (btns) { + var o = this.options; + + for (var i = o.layouts.length - 1; i > 0; i--) { + btns = BI.map(btns, function (k, it) { + return BI.extend({}, o.layouts[i], { + items: [ + BI.extend({}, o.layouts[i].el, it) + ] + }) + }) + } + return btns; + }, + + _packageItems: function (items, packBtns) { + return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); + }, + + _packageLayout: function (items) { + var o = this.options, layout = BI.deepClone(o.layouts[0]); + + var lay = BI.formatEL(layout).el; + while (lay && lay.items && !BI.isEmpty(lay.items)) { + lay = BI.formatEL(lay.items[0]).el; + } + lay.items = items; + return layout; + }, + + populate: function (items) { + var self = this; + items = items || []; + this.options.items = items; + items = this._packageItems(items, this._packageBtns(this._createBtns(items))); + if (!this.layouts) { + this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); + } else { + this.layouts.populate(this._packageLayout(items).items); + } + } +}); +BI.VirtualGroup.EVENT_CHANGE = "EVENT_CHANGE"; + +$.shortcut("bi.virtual_group", BI.VirtualGroup);/** * 加载控件 * * Created by GUY on 2015/8/31. diff --git a/dist/core.js b/dist/core.js index f21704bf5..0977f781f 100644 --- a/dist/core.js +++ b/dist/core.js @@ -14342,6 +14342,10 @@ BI.Widget = BI.inherit(BI.OB, { }, + update: function () { + + }, + destroyed: function () { }, @@ -14666,10 +14670,7 @@ BI.Widget = BI.inherit(BI.OB, { }, destroy: function () { - this.empty(); - this._isMounted = false; - this._parent = null; - this.destroyed(); + this._unMount(); this.element.destroy(); this.fireEvent(BI.Events.DESTROY); } @@ -19320,35 +19321,117 @@ BI.Layout = BI.inherit(BI.Widget, { } }, + _getChildName: function (index) { + return index + ""; + }, + _addElement: function (i, item) { - var o = this.options; - var w; - if (!this.hasWidget(this.getName() + "-" + i)) { + var self = this, w; + if (!this.hasWidget(this._getChildName(i))) { w = BI.createWidget(item); - this.addWidget(this.getName() + "-" + i, w); + this.addWidget(this._getChildName(i), w); + w.on(BI.Events.DESTROY, function () { + BI.each(self._children, function (name, child) { + if (child === w) { + self.removeItemAt(name | 0); + } + }); + }); } else { - w = this.getWidgetByName(this.getName() + "-" + i); + w = this.getWidgetByName(this._getChildName(i)); } return w; }, - stroke: function (items) { + _getOptions: function (item) { + if (item instanceof BI.Widget) { + item = item.options; + } + item = BI.stripEL(item); + if (item instanceof BI.Widget) { + item = item.options; + } + return item; + }, + + _compare: function (item1, item2) { var self = this; - BI.each(items, function (i, item) { - if (!!item) { - self._addElement(i, item); + return eq(item1, item2); + + //不比较函数 + function eq(a, b, aStack, bStack) { + if (a === b) return a !== 0 || 1 / a === 1 / b; + if (a == null || b == null) return a === b; + var className = Object.prototype.toString.call(a); + switch (className) { + case '[object RegExp]': + case '[object String]': + return '' + a === '' + b; + case '[object Number]': + if (+a !== +a) return +b !== +b; + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + return +a === +b; + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (BI.isFunction(a) && BI.isFunction(b)) { + return true; + } + a = self._getOptions(a); + b = self._getOptions(b); } - }); + + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + if (aStack[length] === a) return bStack[length] === b; + } + + aStack.push(a); + bStack.push(b); + + if (areArrays) { + length = a.length; + if (length !== b.length) return false; + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + var keys = _.keys(a), key; + length = keys.length; + if (_.keys(b).length !== length) return false; + while (length--) { + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + aStack.pop(); + bStack.pop(); + return true; + } }, - populate: function (items) { - var self = this; - this.options.items = items || []; - this.stroke(items); + _getWrapper: function () { + return this.element; }, - resize: function () { + _addItem: function (index, item) { + for (var i = this.options.items.length; i > index; i--) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i - 1)]; + } + delete this._children[index]; + this.options.items.splice(index, 0, item); + }, + _removeItem: function (index) { + for (var i = index; i < this.options.items.length - 1; i++) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i + 1)]; + } + this.options.items.splice(index, 1); }, /** @@ -19358,7 +19441,7 @@ BI.Layout = BI.inherit(BI.Widget, { addItem: function (item) { var w = this._addElement(this.options.items.length, item); this.options.items.push(item); - w.element.appendTo(this.element); + w.element.appendTo(this._getWrapper()); w._mount(); return w; }, @@ -19366,11 +19449,54 @@ BI.Layout = BI.inherit(BI.Widget, { prependItem: function (item) { var w = this._addElement(this.options.items.length, item); this.options.items.unshift(item); - w.element.prependTo(this.element); + w.element.prependTo(this._getWrapper()); w._mount(); return w; }, + addItemAt: function (index, item) { + if (index < 0 || index > this.options.items.length) { + return; + } + this._addItem(index, item); + var w = this._addElement(index, item); + if (index > 0) { + this._children[this._getChildName(index - 1)].element.after(w.element); + } else { + w.element.prependTo(this._getWrapper()); + } + w._mount(); + return w; + }, + + removeItemAt: function (index) { + if (index < 0 || index > this.options.items.length - 1) { + return; + } + this._children[this._getChildName(index)].destroy(); + this._removeItem(index); + }, + + updateItemAt: function (index, item) { + if (index < 0 || index > this.options.items.length - 1) { + return; + } + + var updated; + if (updated = this._children[this._getChildName(index)].update(this._getOptions(item))) { + return updated; + } + this._children[this._getChildName(index)].destroy(); + var w = this._addElement(index, item); + this._children[this._getChildName(index)] = w; + if (index > 0) { + this._children[this._getChildName(index - 1)].element.after(w.element); + } else { + w.element.prependTo(this._getWrapper()); + } + w._mount(); + }, + addItems: function (items) { var self = this; BI.each(items, function (i, item) { @@ -19386,9 +19512,9 @@ BI.Layout = BI.inherit(BI.Widget, { }, getValue: function () { - var value = []; - BI.each(this._children, function (i, wi) { - var v = wi.getValue(); + var self = this, value = []; + BI.each(this.options.items, function (i) { + var v = self._children[self._getChildName(i)].getValue(); v = BI.isArray(v) ? v : [v]; value = value.concat(v); }); @@ -19396,15 +19522,63 @@ BI.Layout = BI.inherit(BI.Widget, { }, setValue: function (v) { - BI.each(this._children, function (i, wi) { - wi.setValue(v); + var self = this; + BI.each(this.options.items, function (i) { + self._children[self._getChildName(i)].setValue(v); }) }, setText: function (v) { - BI.each(this._children, function (i, wi) { - wi.setText(v); + var self = this; + BI.each(this.options.items, function (i) { + self._children[self._getChildName(i)].setText(v); }) + }, + + update: function (item) { + var o = this.options; + var items = item.items; + var updated = false, i, len; + for (i = 0, len = o.items.length; i < len; i++) { + if (!this._compare(o.items[i], items[i])) { + updated = this.updateItemAt(i, items[i]) || updated; + } + } + if (o.items.length > items.length) { + for (i = items.length; i < o.items.length; i++) { + this.removeItemAt(i); + } + } else if (items.length > o.items.length) { + for (i = o.items.length; i < items.length; i++) { + this.addItemAt(i, items[i]); + } + } + this.options.items = items; + return updated; + }, + + stroke: function (items) { + var self = this; + BI.each(items, function (i, item) { + if (!!item) { + self._addElement(i, item); + } + }); + }, + + populate: function (items) { + var self = this, o = this.options; + items = items || []; + if (this._isMounted) { + this.update({items: items}); + return; + } + this.options.items = items; + this.stroke(items); + }, + + resize: function () { + } }); $.shortcut('bi.layout', BI.Layout);/** @@ -24978,7 +25152,7 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -24989,9 +25163,9 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } td.element.css({"max-width": o.columnSize[i]}); @@ -25049,20 +25223,8 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { // console.log("center_adapt布局不需要resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function(){ + return this.$tr; }, populate: function (items) { @@ -25108,7 +25270,7 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -25119,9 +25281,9 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } td.element.css({"max-width": o.columnSize[i] + "px"}); @@ -25178,20 +25340,8 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { // console.log("horizontal_adapt布局不需要resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function () { + return this.$tr; }, populate: function (items) { @@ -25406,7 +25556,7 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -25417,9 +25567,9 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } @@ -25473,20 +25623,8 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function(){ + return this.$tr; }, resize: function () { @@ -26063,20 +26201,8 @@ BI.FlexCenterLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { @@ -26160,20 +26286,8 @@ BI.FlexHorizontalLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { @@ -26255,20 +26369,8 @@ BI.FlexVerticalCenter = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { @@ -27275,7 +27377,7 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "margin": "0px auto"}); td = BI.createWidget({ @@ -27286,9 +27388,9 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } @@ -27346,12 +27448,8 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { // console.log("horizontal layout do not need to resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - w._mount(); - this.options.items.push(item); - w.element.appendTo(this.$tr); - return w; + _getWrapper: function(){ + return this.$tr; }, populate: function (items) { @@ -27522,6 +27620,12 @@ BI.LatticeLayout = BI.inherit(BI.Layout, { return w; }, + addItemAt: function (item) { + var w = BI.LatticeLayout.superclass.addItemAt.apply(this, arguments); + this.resize(); + return w; + }, + resize: function () { this.stroke(this.options.items); }, diff --git a/src/base/combination/group.button.js b/src/base/combination/group.button.js index abe2310bc..c406acffb 100644 --- a/src/base/combination/group.button.js +++ b/src/base/combination/group.button.js @@ -166,11 +166,12 @@ BI.ButtonGroup = BI.inherit(BI.Widget, { }, populate: function (items) { - this.options.items = items || []; + items = items || []; + this.options.items = items; this.empty(); this.buttons = this._btnsCreator.apply(this, arguments); - var items = this._packageItems(items, this._packageBtns(this.buttons)); + items = this._packageItems(items, this._packageBtns(this.buttons)); this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); }, diff --git a/src/base/combination/group.virtual.js b/src/base/combination/group.virtual.js new file mode 100644 index 000000000..3f4de579d --- /dev/null +++ b/src/base/combination/group.virtual.js @@ -0,0 +1,69 @@ +BI.VirtualGroup = BI.inherit(BI.Widget, { + _defaultConfig: function () { + return BI.extend(BI.VirtualGroup.superclass._defaultConfig.apply(this, arguments), { + baseCls: "bi-virtual-group", + items: [], + layouts: [{ + type: "bi.center", + hgap: 0, + vgap: 0 + }] + }) + }, + + render: function () { + this.populate(this.options.items); + }, + + _createBtns: function (items) { + var o = this.options; + return BI.createItems(items, { + type: "bi.text_button" + }); + }, + + _packageBtns: function (btns) { + var o = this.options; + + for (var i = o.layouts.length - 1; i > 0; i--) { + btns = BI.map(btns, function (k, it) { + return BI.extend({}, o.layouts[i], { + items: [ + BI.extend({}, o.layouts[i].el, it) + ] + }) + }) + } + return btns; + }, + + _packageItems: function (items, packBtns) { + return BI.createItems(BI.makeArrayByArray(items, {}), BI.clone(packBtns)); + }, + + _packageLayout: function (items) { + var o = this.options, layout = BI.deepClone(o.layouts[0]); + + var lay = BI.formatEL(layout).el; + while (lay && lay.items && !BI.isEmpty(lay.items)) { + lay = BI.formatEL(lay.items[0]).el; + } + lay.items = items; + return layout; + }, + + populate: function (items) { + var self = this; + items = items || []; + this.options.items = items; + items = this._packageItems(items, this._packageBtns(this._createBtns(items))); + if (!this.layouts) { + this.layouts = BI.createWidget(BI.extend({element: this}, this._packageLayout(items))); + } else { + this.layouts.populate(this._packageLayout(items).items); + } + } +}); +BI.VirtualGroup.EVENT_CHANGE = "EVENT_CHANGE"; + +$.shortcut("bi.virtual_group", BI.VirtualGroup); \ No newline at end of file diff --git a/src/base/combination/map.button.js b/src/base/combination/map.button.js deleted file mode 100644 index 365f6bc15..000000000 --- a/src/base/combination/map.button.js +++ /dev/null @@ -1,115 +0,0 @@ -/** - * value作为key值缓存button, 不支持顺序读写 - * 适合用于频繁增删的一组button - * Created by GUY on 2015/8/10. - * @class BI.ButtonMap - * @extends BI.ButtonTree - */ - -BI.ButtonMap = BI.inherit(BI.ButtonTree, { - _defaultConfig: function () { - return BI.extend(BI.ButtonMap.superclass._defaultConfig.apply(this, arguments), { - baseCls: "bi-button-map" - }) - }, - - _init: function () { - BI.ButtonMap.superclass._init.apply(this, arguments); - }, - - _createBtns: function (items) { - var self = this, o = this.options; - var buttons = BI.createWidgets(BI.createItems(items, {type: "bi.text_button", once: o.chooseType === 0})); - var keys = BI.map(items, function (i, item) { - item = BI.stripEL(item); - if (!(BI.isKey(item.id) || BI.isKey(item.value))) { - throw new Error("item必须包含id或value属性"); - } - return item.id || item.value; - }); - return BI.object(keys, buttons); - }, - - setValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(true); - } else { - item.setSelected && item.setSelected(false); - } - }); - }, - - setNotSelectedValue: function (v) { - var self = this; - v = BI.isArray(v) ? v : [v]; - BI.each(this.buttons, function (val, item) { - if (!BI.isFunction(item.setSelected)) { - item.setNotSelectedValue(v); - return; - } - if (v.contains(val)) { - item.setSelected && item.setSelected(false); - } else { - item.setSelected && item.setSelected(true); - } - }); - }, - - populate: function (items) { - var self = this; - var args = [].slice.call(arguments); - var linkHashMap = new BI.LinkHashMap(); - var val = function (item) { - return item.id || item.value; - }; - if (!this.buttons) { - this.buttons = {}; - } - //所有已存在的和新添加的 - var willCreated = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - if (self.buttons[val(item)]) { - var ob = self.buttons[val(item)]; - args[0] = item.items; - args[2] = item; - ob.populate && ob.populate.apply(ob, args); - } else { - willCreated.push(item); - } - }); - //创建新元素 - args[0] = willCreated; - var newBtns = this._btnsCreator.apply(this, args); - - //整理 - var array = []; - BI.each(items, function (i, item) { - item = BI.stripEL(item); - var button = self.buttons[val(item)] || newBtns[val(item)]; - linkHashMap.add(val(item), button); - array.push(button); - }); - this.buttons = linkHashMap.map; - - BI.DOM.hang(this.buttons); - this.empty(); - - var packages = this._packageItems(items, this._packageBtns(array)); - BI.createWidget(BI.extend({element: this}, this._packageLayout(packages))); - }, - - getIndexByValue: function (value) { - throw new Error("不能使用getIndexByValue方法"); - } -}); -BI.ButtonMap.EVENT_CHANGE = "EVENT_CHANGE"; - -$.shortcut("bi.button_map", BI.ButtonMap); \ No newline at end of file diff --git a/src/core/widget.js b/src/core/widget.js index 570cff7c3..b5d1f5666 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -43,6 +43,10 @@ BI.Widget = BI.inherit(BI.OB, { }, + update: function () { + + }, + destroyed: function () { }, @@ -367,10 +371,7 @@ BI.Widget = BI.inherit(BI.OB, { }, destroy: function () { - this.empty(); - this._isMounted = false; - this._parent = null; - this.destroyed(); + this._unMount(); this.element.destroy(); this.fireEvent(BI.Events.DESTROY); } diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js index 4bc18481d..b805c7501 100644 --- a/src/core/wrapper/layout.js +++ b/src/core/wrapper/layout.js @@ -63,35 +63,117 @@ BI.Layout = BI.inherit(BI.Widget, { } }, + _getChildName: function (index) { + return index + ""; + }, + _addElement: function (i, item) { - var o = this.options; - var w; - if (!this.hasWidget(this.getName() + "-" + i)) { + var self = this, w; + if (!this.hasWidget(this._getChildName(i))) { w = BI.createWidget(item); - this.addWidget(this.getName() + "-" + i, w); + this.addWidget(this._getChildName(i), w); + w.on(BI.Events.DESTROY, function () { + BI.each(self._children, function (name, child) { + if (child === w) { + self.removeItemAt(name | 0); + } + }); + }); } else { - w = this.getWidgetByName(this.getName() + "-" + i); + w = this.getWidgetByName(this._getChildName(i)); } return w; }, - stroke: function (items) { + _getOptions: function (item) { + if (item instanceof BI.Widget) { + item = item.options; + } + item = BI.stripEL(item); + if (item instanceof BI.Widget) { + item = item.options; + } + return item; + }, + + _compare: function (item1, item2) { var self = this; - BI.each(items, function (i, item) { - if (!!item) { - self._addElement(i, item); + return eq(item1, item2); + + //不比较函数 + function eq(a, b, aStack, bStack) { + if (a === b) return a !== 0 || 1 / a === 1 / b; + if (a == null || b == null) return a === b; + var className = Object.prototype.toString.call(a); + switch (className) { + case '[object RegExp]': + case '[object String]': + return '' + a === '' + b; + case '[object Number]': + if (+a !== +a) return +b !== +b; + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + return +a === +b; } - }); + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (BI.isFunction(a) && BI.isFunction(b)) { + return true; + } + a = self._getOptions(a); + b = self._getOptions(b); + } + + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + if (aStack[length] === a) return bStack[length] === b; + } + + aStack.push(a); + bStack.push(b); + + if (areArrays) { + length = a.length; + if (length !== b.length) return false; + while (length--) { + if (!eq(a[length], b[length], aStack, bStack)) return false; + } + } else { + var keys = _.keys(a), key; + length = keys.length; + if (_.keys(b).length !== length) return false; + while (length--) { + key = keys[length]; + if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; + } + } + aStack.pop(); + bStack.pop(); + return true; + } }, - populate: function (items) { - var self = this; - this.options.items = items || []; - this.stroke(items); + _getWrapper: function () { + return this.element; }, - resize: function () { + _addItem: function (index, item) { + for (var i = this.options.items.length; i > index; i--) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i - 1)]; + } + delete this._children[index]; + this.options.items.splice(index, 0, item); + }, + _removeItem: function (index) { + for (var i = index; i < this.options.items.length - 1; i++) { + this._children[this._getChildName(i)] = this._children[this._getChildName(i + 1)]; + } + this.options.items.splice(index, 1); }, /** @@ -101,7 +183,7 @@ BI.Layout = BI.inherit(BI.Widget, { addItem: function (item) { var w = this._addElement(this.options.items.length, item); this.options.items.push(item); - w.element.appendTo(this.element); + w.element.appendTo(this._getWrapper()); w._mount(); return w; }, @@ -109,11 +191,54 @@ BI.Layout = BI.inherit(BI.Widget, { prependItem: function (item) { var w = this._addElement(this.options.items.length, item); this.options.items.unshift(item); - w.element.prependTo(this.element); + w.element.prependTo(this._getWrapper()); w._mount(); return w; }, + addItemAt: function (index, item) { + if (index < 0 || index > this.options.items.length) { + return; + } + this._addItem(index, item); + var w = this._addElement(index, item); + if (index > 0) { + this._children[this._getChildName(index - 1)].element.after(w.element); + } else { + w.element.prependTo(this._getWrapper()); + } + w._mount(); + return w; + }, + + removeItemAt: function (index) { + if (index < 0 || index > this.options.items.length - 1) { + return; + } + this._children[this._getChildName(index)].destroy(); + this._removeItem(index); + }, + + updateItemAt: function (index, item) { + if (index < 0 || index > this.options.items.length - 1) { + return; + } + + var updated; + if (updated = this._children[this._getChildName(index)].update(this._getOptions(item))) { + return updated; + } + this._children[this._getChildName(index)].destroy(); + var w = this._addElement(index, item); + this._children[this._getChildName(index)] = w; + if (index > 0) { + this._children[this._getChildName(index - 1)].element.after(w.element); + } else { + w.element.prependTo(this._getWrapper()); + } + w._mount(); + }, + addItems: function (items) { var self = this; BI.each(items, function (i, item) { @@ -129,9 +254,9 @@ BI.Layout = BI.inherit(BI.Widget, { }, getValue: function () { - var value = []; - BI.each(this._children, function (i, wi) { - var v = wi.getValue(); + var self = this, value = []; + BI.each(this.options.items, function (i) { + var v = self._children[self._getChildName(i)].getValue(); v = BI.isArray(v) ? v : [v]; value = value.concat(v); }); @@ -139,15 +264,63 @@ BI.Layout = BI.inherit(BI.Widget, { }, setValue: function (v) { - BI.each(this._children, function (i, wi) { - wi.setValue(v); + var self = this; + BI.each(this.options.items, function (i) { + self._children[self._getChildName(i)].setValue(v); }) }, setText: function (v) { - BI.each(this._children, function (i, wi) { - wi.setText(v); + var self = this; + BI.each(this.options.items, function (i) { + self._children[self._getChildName(i)].setText(v); }) + }, + + update: function (item) { + var o = this.options; + var items = item.items; + var updated = false, i, len; + for (i = 0, len = o.items.length; i < len; i++) { + if (!this._compare(o.items[i], items[i])) { + updated = this.updateItemAt(i, items[i]) || updated; + } + } + if (o.items.length > items.length) { + for (i = items.length; i < o.items.length; i++) { + this.removeItemAt(i); + } + } else if (items.length > o.items.length) { + for (i = o.items.length; i < items.length; i++) { + this.addItemAt(i, items[i]); + } + } + this.options.items = items; + return updated; + }, + + stroke: function (items) { + var self = this; + BI.each(items, function (i, item) { + if (!!item) { + self._addElement(i, item); + } + }); + }, + + populate: function (items) { + var self = this, o = this.options; + items = items || []; + if (this._isMounted) { + this.update({items: items}); + return; + } + this.options.items = items; + this.stroke(items); + }, + + resize: function () { + } }); $.shortcut('bi.layout', BI.Layout); \ No newline at end of file diff --git a/src/core/wrapper/layout/adapt/adapt.center.js b/src/core/wrapper/layout/adapt/adapt.center.js index 072d929bd..a6fe5c9dd 100644 --- a/src/core/wrapper/layout/adapt/adapt.center.js +++ b/src/core/wrapper/layout/adapt/adapt.center.js @@ -36,7 +36,7 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -47,9 +47,9 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } td.element.css({"max-width": o.columnSize[i]}); @@ -107,20 +107,8 @@ BI.CenterAdaptLayout = BI.inherit(BI.Layout, { // console.log("center_adapt布局不需要resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function(){ + return this.$tr; }, populate: function (items) { diff --git a/src/core/wrapper/layout/adapt/adapt.horizontal.js b/src/core/wrapper/layout/adapt/adapt.horizontal.js index dbcb42a15..004217555 100644 --- a/src/core/wrapper/layout/adapt/adapt.horizontal.js +++ b/src/core/wrapper/layout/adapt/adapt.horizontal.js @@ -36,7 +36,7 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -47,9 +47,9 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } td.element.css({"max-width": o.columnSize[i] + "px"}); @@ -106,20 +106,8 @@ BI.HorizontalAdaptLayout = BI.inherit(BI.Layout, { // console.log("horizontal_adapt布局不需要resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function () { + return this.$tr; }, populate: function (items) { diff --git a/src/core/wrapper/layout/adapt/adapt.vertical.js b/src/core/wrapper/layout/adapt/adapt.vertical.js index e4cf6de7a..473083050 100644 --- a/src/core/wrapper/layout/adapt/adapt.vertical.js +++ b/src/core/wrapper/layout/adapt/adapt.vertical.js @@ -33,7 +33,7 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + "-" + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "top": "0", "left": "0", "margin": "0px auto"}); td = BI.createWidget({ @@ -44,9 +44,9 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + "-" + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + "-" + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } @@ -100,20 +100,8 @@ BI.VerticalAdaptLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$tr); - w._mount(); - return w; + _getWrapper: function(){ + return this.$tr; }, resize: function () { diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js index 1f23508c9..fb3f95fcd 100644 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js +++ b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.center.js @@ -40,20 +40,8 @@ BI.FlexCenterLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js index 1aff0d676..4214b2c80 100644 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js +++ b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.horizontal.js @@ -70,20 +70,8 @@ BI.FlexHorizontalLayout = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { diff --git a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js index 32da933fd..96cd78078 100644 --- a/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js +++ b/src/core/wrapper/layout/flex/wrapper/flex.wrapper.vertical.center.js @@ -68,20 +68,8 @@ BI.FlexVerticalCenter = BI.inherit(BI.Layout, { } }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.push(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; - }, - - prependItem: function (item) { - var w = this._addElement(this.options.items.length, item); - this.options.items.unshift(item); - w.element.appendTo(this.$wrapper); - w._mount(); - return w; + _getWrapper: function(){ + return this.$wrapper; }, resize: function () { diff --git a/src/core/wrapper/layout/layout.horizontal.js b/src/core/wrapper/layout/layout.horizontal.js index eabd14174..94d30683d 100644 --- a/src/core/wrapper/layout/layout.horizontal.js +++ b/src/core/wrapper/layout/layout.horizontal.js @@ -36,7 +36,7 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { var o = this.options; var td; var width = o.columnSize[i] <= 1 ? (o.columnSize[i] * 100 + "%") : o.columnSize[i]; - if (!this.hasWidget(this.getName() + i)) { + if (!this.hasWidget(this._getChildName(i))) { var w = BI.createWidget(item); w.element.css({"position": "relative", "margin": "0px auto"}); td = BI.createWidget({ @@ -47,9 +47,9 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { }, items: [w] }); - this.addWidget(this.getName() + i, td); + this.addWidget(this._getChildName(i), td); } else { - td = this.getWidgetByName(this.getName() + i); + td = this.getWidgetByName(this._getChildName(i)); td.element.attr("width", width); } @@ -107,12 +107,8 @@ BI.HorizontalLayout = BI.inherit(BI.Layout, { // console.log("horizontal layout do not need to resize"); }, - addItem: function (item) { - var w = this._addElement(this.options.items.length, item); - w._mount(); - this.options.items.push(item); - w.element.appendTo(this.$tr); - return w; + _getWrapper: function(){ + return this.$tr; }, populate: function (items) { diff --git a/src/core/wrapper/layout/layout.lattice.js b/src/core/wrapper/layout/layout.lattice.js index 4f21ae806..6bbe195df 100644 --- a/src/core/wrapper/layout/layout.lattice.js +++ b/src/core/wrapper/layout/layout.lattice.js @@ -37,6 +37,12 @@ BI.LatticeLayout = BI.inherit(BI.Layout, { return w; }, + addItemAt: function (item) { + var w = BI.LatticeLayout.superclass.addItemAt.apply(this, arguments); + this.resize(); + return w; + }, + resize: function () { this.stroke(this.options.items); },