From 5fb75ef130a517e53b39421b384fa27914ccf0e0 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 12:07:02 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0updateModel=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=EF=BC=8C=E5=8F=AF=E4=BB=A5=E9=85=8D=E7=BD=AE=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E6=A8=A1=E5=BC=8F=EF=BC=8C=E8=87=AA=E5=8A=A8watch?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=B9=B6=E5=93=8D=E5=BA=94=E5=8F=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 3 + dev.html | 103 +++++++++++++++++++++++ dist/fix/fix.compact.js | 73 ++++++++++++++++ src/base/single/button/buttons/button.js | 6 +- src/base/single/single.js | 11 ++- src/core/ob.js | 7 ++ src/core/widget.js | 27 +++++- src/core/wrapper/layout.js | 14 ++- 8 files changed, 229 insertions(+), 15 deletions(-) create mode 100644 dev.html diff --git a/changelog.md b/changelog.md index fd7e96c5c..6574a00bf 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 000000000..650cf45a6 --- /dev/null +++ b/dev.html @@ -0,0 +1,103 @@ + + + + + + + + +
+ + + diff --git a/dist/fix/fix.compact.js b/dist/fix/fix.compact.js index 2e00a6c1d..80c7380e7 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 05819b04f..6db1349a3 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 d2b51f0d0..2ad590597 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 c4aacf624..9eab5d35a 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 3f2779c63..49d0d05a1 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 5d4fdc470..6342575ff 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); } }, From 36e366defcfc86f70bb879afac8bca3e69b6a024 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 12:50:04 +0800 Subject: [PATCH 2/9] update --- src/core/wrapper/layout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js index 6342575ff..8013ca093 100644 --- a/src/core/wrapper/layout.js +++ b/src/core/wrapper/layout.js @@ -268,7 +268,7 @@ BI.Layout = BI.inherit(BI.Widget, { if (!child.shouldUpdate) { return null; } - return child.shouldUpdate(this._getOptions(item)) !== false; + return child.shouldUpdate(this._getOptions(item)); }, updateItemAt: function (index, item) { From 9121571a38873f17c2e6a834ad96ba1402e7dfb4 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 13:26:08 +0800 Subject: [PATCH 3/9] update --- dist/fix/fix.compact.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dist/fix/fix.compact.js b/dist/fix/fix.compact.js index 80c7380e7..75eb3425b 100644 --- a/dist/fix/fix.compact.js +++ b/dist/fix/fix.compact.js @@ -187,11 +187,10 @@ var self = this; var render = BI.isFunction(this.options.render) ? this.options.render : this.render; var els; - if (this.options.updateMode === "auto") { + if (this.options.updateMode === "auto" && this._store) { // 自动更新模式 var childComponents = {}; var rendered = false; - initWatch(this, {}); this._watchers.push(Fix.watch(this.model, function () { if (rendered) { var newEls = render && render.call(this); From 6dc4355e1c2ab5d2c616fbc476a117c84a03f2fc Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 14:25:00 +0800 Subject: [PATCH 4/9] update --- dist/fix/fix.compact.js | 8 ++------ src/core/widget.js | 24 ++++++++++++++---------- src/core/wrapper/layout.js | 7 +++++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/dist/fix/fix.compact.js b/dist/fix/fix.compact.js index 75eb3425b..affb9a10b 100644 --- a/dist/fix/fix.compact.js +++ b/dist/fix/fix.compact.js @@ -197,12 +197,8 @@ 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); - } + var shouldUpdate = childComponent.component.shouldUpdate && childComponent.component.shouldUpdate(nextProps); + childComponent.component._update(nextProps, shouldUpdate); childComponent.props = BI.extend(childComponent.props, nextProps); } }); diff --git a/src/core/widget.js b/src/core/widget.js index 49d0d05a1..f8844ef28 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -74,8 +74,7 @@ shouldUpdate: null, - update: function () { - }, + update: null, beforeUpdate: null, @@ -248,16 +247,21 @@ _mountChildren: null, - _update: function (nextProps) { + _update: function (nextProps, shouldUpdate) { 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); + 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; }, diff --git a/src/core/wrapper/layout.js b/src/core/wrapper/layout.js index 8013ca093..6b10e753d 100644 --- a/src/core/wrapper/layout.js +++ b/src/core/wrapper/layout.js @@ -361,11 +361,14 @@ BI.Layout = BI.inherit(BI.Widget, { patchItem: function (oldVnode, vnode, index) { var shouldUpdate = this.shouldUpdateItem(index, vnode); + var child = this._children[this._getChildName(index)]; if (shouldUpdate) { - var child = this._children[this._getChildName(index)]; - return child._update(shouldUpdate === true ? this._getOptions(vnode) : shouldUpdate); + return child._update(this._getOptions(vnode), shouldUpdate); } if (shouldUpdate === null && !this._compare(oldVnode, vnode)) { + if (child.update) { + return child.update(this._getOptions(vnode)); + } return this.updateItemAt(index, vnode); } }, From 3b5fd7dd126538342aab85bf6f4eebed1d6e4d16 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 14:33:08 +0800 Subject: [PATCH 5/9] update --- src/base/single/single.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/base/single/single.js b/src/base/single/single.js index 2ad590597..5e1cc53f5 100644 --- a/src/base/single/single.js +++ b/src/base/single/single.js @@ -199,7 +199,10 @@ BI.Single = BI.inherit(BI.Widget, { return this.options.value; }, - update: function (props) { + update: function (props, shouldUpdate) { + if (BI.isObject(shouldUpdate)) { + props = shouldUpdate; + } if ("value" in props) { this.setValue(props.value); } From fb32c9ef145f4b082e9ba2bf5b60cb1606ae0a24 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 16:41:06 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9Fmount?= =?UTF-8?q?=EF=BC=8C=E5=85=88=E6=8A=8A=E5=AD=90dom=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=AE=8C=E5=86=8D=E6=95=B4=E4=B8=AA=E4=B8=80?= =?UTF-8?q?=E8=B5=B7append=E5=88=B0=E7=88=B6=E8=8A=82=E7=82=B9=E4=B8=8A?= =?UTF-8?q?=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev.html | 23 ++++++++++++++--------- src/core/widget.js | 20 +++++++++++++++++--- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/dev.html b/dev.html index 650cf45a6..9aa2fc79a 100644 --- a/dev.html +++ b/dev.html @@ -70,24 +70,26 @@ var store = BI.useStore(function () { return BI.Models.getModel("demo.model"); }); - setInterval(function () { - store.toggle(); - }, 1000); + // setInterval(function () { + // store.toggle(); + // }, 1000); return function () { return { type: "bi.vertical", vgap: 20, - items: [{ - type: "demo.child" - }, { - type: "demo.child" - }] + items: BI.makeArray(10000).map(function (i) { + return { + type: "bi.label", + text: i + }; + }) }; }; } }); BI.shortcut("demo.parent", Widget); - BI.createWidget({ + var time = performance.now(); + var widget = BI.createWidget({ type: "bi.absolute", items: [{ el: { @@ -97,7 +99,10 @@ left: 100 }], element: "#wrapper" + // root: true }); + // widget.element.appendTo("#wrapper"); + console.log(performance.now() - time); diff --git a/src/core/widget.js b/src/core/widget.js index f8844ef28..7b6b341f9 100644 --- a/src/core/widget.js +++ b/src/core/widget.js @@ -227,22 +227,36 @@ * @private */ _mount: function (force, deep, lifeHook, predicate) { + if (this.__beforeMount(force, deep, lifeHook, predicate)) { + this.__afterMount(lifeHook, predicate); + return true; + } + return false; + }, + + __beforeMount: function (force, deep, lifeHook, predicate) { var self = this; if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) { return false; } lifeHook !== false && callLifeHook(this, "beforeMount"); this._isMounted = true; - this._mountChildren && this._mountChildren(); BI.each(this._children, function (i, widget) { !self.isEnabled() && widget._setEnable(false); !self.isValid() && widget._setValid(false); - widget._mount && widget._mount(deep ? force : false, deep, lifeHook, predicate); + widget.__beforeMount && widget.__beforeMount(deep ? force : false, deep, lifeHook, predicate); + }); + this._mountChildren && this._mountChildren(); + return true; + }, + + __afterMount: function (lifeHook, predicate) { + BI.each(this._children, function (i, widget) { + widget.__afterMount && widget.__afterMount(lifeHook, predicate); }); lifeHook !== false && callLifeHook(this, "mounted"); this.fireEvent(BI.Events.MOUNT); predicate && predicate(this); - return true; }, _mountChildren: null, From 3bc1eb890d3d0c4145e5d3d3e1efd40438f71acd Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 16:41:35 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9Fmount?= =?UTF-8?q?=EF=BC=8C=E5=85=88=E6=8A=8A=E5=AD=90dom=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E5=AE=8C=E5=86=8D=E6=95=B4=E4=B8=AA=E4=B8=80?= =?UTF-8?q?=E8=B5=B7append=E5=88=B0=E7=88=B6=E8=8A=82=E7=82=B9=E4=B8=8A?= =?UTF-8?q?=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dev.html | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/dev.html b/dev.html index 9aa2fc79a..650cf45a6 100644 --- a/dev.html +++ b/dev.html @@ -70,26 +70,24 @@ var store = BI.useStore(function () { return BI.Models.getModel("demo.model"); }); - // setInterval(function () { - // store.toggle(); - // }, 1000); + setInterval(function () { + store.toggle(); + }, 1000); return function () { return { type: "bi.vertical", vgap: 20, - items: BI.makeArray(10000).map(function (i) { - return { - type: "bi.label", - text: i - }; - }) + items: [{ + type: "demo.child" + }, { + type: "demo.child" + }] }; }; } }); BI.shortcut("demo.parent", Widget); - var time = performance.now(); - var widget = BI.createWidget({ + BI.createWidget({ type: "bi.absolute", items: [{ el: { @@ -99,10 +97,7 @@ left: 100 }], element: "#wrapper" - // root: true }); - // widget.element.appendTo("#wrapper"); - console.log(performance.now() - time); From a70f3a8d611fbe0a73babdf72cffcff1003aec05 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 18:28:53 +0800 Subject: [PATCH 8/9] update --- src/base/single/button/button.basic.js | 5 ----- src/base/single/single.js | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/base/single/button/button.basic.js b/src/base/single/button/button.basic.js index 2bd82b17d..4a5d68a0c 100644 --- a/src/base/single/button/button.basic.js +++ b/src/base/single/button/button.basic.js @@ -389,11 +389,6 @@ BI.BasicButton = BI.inherit(BI.Single, { return this.options.text; }, - setValue: function (value) { - BI.BasicButton.superclass.setValue.apply(this, arguments); - this.options.setValue && this.options.setValue.call(this, value); - }, - _setEnable: function (enable) { BI.BasicButton.superclass._setEnable.apply(this, arguments); if (enable === true) { diff --git a/src/base/single/single.js b/src/base/single/single.js index 5e1cc53f5..da689d42c 100644 --- a/src/base/single/single.js +++ b/src/base/single/single.js @@ -192,6 +192,7 @@ BI.Single = BI.inherit(BI.Widget, { setValue: function (val) { if (!this.options.readonly) { this.options.value = val; + this.options.setValue && this.options.setValue(val); } }, @@ -219,3 +220,4 @@ BI.Single = BI.inherit(BI.Widget, { BI.Tooltips.remove(this.getName()); } }); +BI.shortcut("bi.single", BI.Single); From 1438bbf5d89d8517e5220e95c7cc9810af3442f9 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 28 Feb 2021 18:29:58 +0800 Subject: [PATCH 9/9] update --- src/base/single/single.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base/single/single.js b/src/base/single/single.js index da689d42c..c4d15291d 100644 --- a/src/base/single/single.js +++ b/src/base/single/single.js @@ -208,7 +208,7 @@ BI.Single = BI.inherit(BI.Widget, { this.setValue(props.value); } if ("text" in props) { - this.setText(props.text); + this.setText && this.setText(props.text); } },