diff --git a/changelog.md b/changelog.md index fd7e96c5ce..6574a00bf0 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # 更新日志 +2.0(2021-02) +- 增加updateModel属性,可以配置自动模式,自动watch属性并响应变化 + 2.0(2021-01) - 修改了日期下拉面板中的当前时间按钮的交互效果 - 新增年区间和年季度区间控件 diff --git a/dev.html b/dev.html new file mode 100644 index 0000000000..650cf45a6b --- /dev/null +++ b/dev.html @@ -0,0 +1,103 @@ + + + + + + + + +
+ + + diff --git a/dist/fix/fix.compact.js b/dist/fix/fix.compact.js index 2e00a6c1d1..80c7380e70 100644 --- a/dist/fix/fix.compact.js +++ b/dist/fix/fix.compact.js @@ -183,6 +183,79 @@ needPop && popTarget(); }; + BI.Widget.prototype._initElement = function () { + var self = this; + var render = BI.isFunction(this.options.render) ? this.options.render : this.render; + var els; + if (this.options.updateMode === "auto") { + // 自动更新模式 + var childComponents = {}; + var rendered = false; + initWatch(this, {}); + this._watchers.push(Fix.watch(this.model, function () { + if (rendered) { + var newEls = render && render.call(this); + BI.each(childComponents, function (i, childComponent) { + var nextProps = BI.get([newEls], childComponent.path); + if (nextProps) { + var shouldUpdate; + if (shouldUpdate = (childComponent.component.shouldUpdate && childComponent.component.shouldUpdate(nextProps))) { + childComponent.component._update(shouldUpdate === true ? nextProps : shouldUpdate); + } else { + childComponent.component._update(nextProps); + } + childComponent.props = BI.extend(childComponent.props, nextProps); + } + }); + } else { + els = render && render.call(this); + + function traverse (parent, path) { + BI.each(parent, function (i, child) { + const childPath = path.concat(i); + if (BI.isArray(child)) { + traverse(child, childPath); + } else if (BI.isPlainObject(child)) { + if (child.type) { + child.__ref = function (_ref) { + if (_ref) { + var comp = childComponents[this.getName()] = {}; + comp.component = _ref; + comp.props = child; + comp.path = childPath; + } else { + delete childComponents[this.getName()]; + } + }; + } + traverse(child, childPath); + } + }); + } + + traverse([els], []); + rendered = true; + } + })); + } else { + 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(); + }; + var unMount = BI.Widget.prototype.__d; BI.Widget.prototype.__d = function () { try { diff --git a/src/base/single/button/buttons/button.js b/src/base/single/button/buttons/button.js index 05819b04fb..6db1349a3e 100644 --- a/src/base/single/button/buttons/button.js +++ b/src/base/single/button/buttons/button.js @@ -1,4 +1,3 @@ - /** * 文字类型的按钮 * @class BI.Button @@ -44,7 +43,10 @@ BI.Button = BI.inherit(BI.BasicButton, { BI.Button.superclass._init.apply(this, arguments); var o = this.options, self = this; if (BI.isNumber(o.height) && !o.clear && !o.block) { - this.element.css({height: o.height / BI.pixRatio + BI.pixUnit, lineHeight: (o.height - 2) / BI.pixRatio + BI.pixUnit}); + this.element.css({ + height: o.height / BI.pixRatio + BI.pixUnit, + lineHeight: (o.height - 2) / BI.pixRatio + BI.pixUnit + }); } else if (o.clear || o.block) { this.element.css({lineHeight: o.height / BI.pixRatio + BI.pixUnit}); } else { diff --git a/src/base/single/single.js b/src/base/single/single.js index d2b51f0d03..2ad5905978 100644 --- a/src/base/single/single.js +++ b/src/base/single/single.js @@ -199,11 +199,20 @@ BI.Single = BI.inherit(BI.Widget, { return this.options.value; }, + update: function (props) { + if ("value" in props) { + this.setValue(props.value); + } + if ("text" in props) { + this.setText(props.text); + } + }, + destroyed: function () { if (BI.isNotNull(this.showTimeout)) { clearTimeout(this.showTimeout); this.showTimeout = null; } BI.Tooltips.remove(this.getName()); - }, + } }); diff --git a/src/core/ob.js b/src/core/ob.js index c4aacf6242..9eab5d35ae 100644 --- a/src/core/ob.js +++ b/src/core/ob.js @@ -72,6 +72,9 @@ // 获得一个当前对象的引用 _initRef: function () { + if (this.options.__ref) { + this.options.__ref.call(this, this); + } if (this.options.ref) { this.options.ref.call(this, this); } @@ -79,6 +82,10 @@ //释放当前对象 _purgeRef: function () { + if (this.options.__ref) { + this.options.__ref.call(null); + this.options.__ref = null; + } if (this.options.ref) { this.options.ref.call(null); this.options.ref = null; diff --git a/src/core/widget.js b/src/core/widget.js index 3f2779c631..49d0d05a10 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -7,7 +7,7 @@ */ !(function () { - function callLifeHook(self, life) { + function callLifeHook (self, life) { var hook = self.options[life] || self[life]; if (hook) { var hooks = BI.isArray(hook) ? hook : [hook]; @@ -32,7 +32,8 @@ baseCls: "", extraCls: "", cls: "", - css: null + css: null, + updateMode: "manual" // manual / auto }); }, @@ -76,6 +77,10 @@ update: function () { }, + beforeUpdate: null, + + updated: null, + beforeDestroy: null, destroyed: null, @@ -243,6 +248,20 @@ _mountChildren: null, + _update: function (nextProps) { + var o = this.options; + callLifeHook(this, "beforeUpdate"); + var nextChange = {}; + BI.each(nextProps, function (key, value) { + if (o[key] !== value) { + nextChange[key] = value; + } + }); + var res = BI.isNotEmptyObject(nextChange) && this.update(nextChange); + callLifeHook(this, "updated"); + return res; + }, + isMounted: function () { return this._isMounted; }, @@ -534,12 +553,12 @@ BI.Widget.context = context = contextStack.pop(); }; - function pushTarget(_current) { + function pushTarget (_current) { if (current) currentStack.push(current); BI.Widget.current = current = _current; } - function popTarget() { + function popTarget () { BI.Widget.current = current = currentStack.pop(); } diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js index 5d4fdc4700..6342575ff0 100644 --- a/src/core/wrapper/layout.js +++ b/src/core/wrapper/layout.js @@ -268,19 +268,13 @@ BI.Layout = BI.inherit(BI.Widget, { if (!child.shouldUpdate) { return null; } - return child.shouldUpdate(this._getOptions(item)) === true; + return child.shouldUpdate(this._getOptions(item)) !== false; }, updateItemAt: function (index, item) { if (index < 0 || index > this.options.items.length - 1) { return; } - - var child = this._children[this._getChildName(index)]; - var updated; - if (updated = child.update(this._getOptions(item))) { - return updated; - } var del = this._children[this._getChildName(index)]; delete this._children[this._getChildName(index)]; this.options.items.splice(index, 1); @@ -367,7 +361,11 @@ BI.Layout = BI.inherit(BI.Widget, { patchItem: function (oldVnode, vnode, index) { var shouldUpdate = this.shouldUpdateItem(index, vnode); - if (shouldUpdate === true || (shouldUpdate === null && !this._compare(oldVnode, vnode))) { + if (shouldUpdate) { + var child = this._children[this._getChildName(index)]; + return child._update(shouldUpdate === true ? this._getOptions(vnode) : shouldUpdate); + } + if (shouldUpdate === null && !this._compare(oldVnode, vnode)) { return this.updateItemAt(index, vnode); } },