Browse Source

Pull request #1796: 无JIRA任务 增加自动watch机制

Merge in VISUAL/fineui from ~GUY/fineui:master to master

* commit 'e7ff2c2ba7646fe5d005ea835466fe5228b4a01c':
  update
  update
  生命周期mount,先把子dom节点创建完再整个一起append到父节点上去
  生命周期mount,先把子dom节点创建完再整个一起append到父节点上去
  update
  update
  update
  update
  增加updateModel属性,可以配置自动模式,自动watch属性并响应变化
es6
guy 4 years ago
parent
commit
372eb204d6
  1. 3
      changelog.md
  2. 103
      dev.html
  3. 68
      dist/fix/fix.compact.js
  4. 5
      src/base/single/button/button.basic.js
  5. 6
      src/base/single/button/buttons/button.js
  6. 16
      src/base/single/single.js
  7. 7
      src/core/ob.js
  8. 55
      src/core/widget.js
  9. 17
      src/core/wrapper/layout.js

3
changelog.md

@ -1,4 +1,7 @@
# 更新日志 # 更新日志
2.0(2021-02)
- 增加updateModel属性,可以配置自动模式,自动watch属性并响应变化
2.0(2021-01) 2.0(2021-01)
- 修改了日期下拉面板中的当前时间按钮的交互效果 - 修改了日期下拉面板中的当前时间按钮的交互效果
- 新增年区间和年季度区间控件 - 新增年区间和年季度区间控件

103
dev.html

@ -0,0 +1,103 @@
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" type="text/css" href="http://fanruan.design/fineui/2.0/fineui.min.css"/>
<script src="http://localhost:9001/fineui.js"></script>
</head>
<body>
<div id="wrapper"></div>
<script>
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, {
props: {
updateMode: "auto"
},
setup: function () {
var store = BI.useStore(function () {
return BI.Models.getModel("demo.child_model");
});
return {
render: function () {
return {
type: "bi.vertical",
items: [{
type: "bi.button",
text: store.model.text
}, {
type: "bi.label",
text: store.model.text
}]
};
}
};
}
});
BI.shortcut("demo.child", Child);
var Widget = BI.inherit(BI.Widget, {
props: {
updateMode: "auto"
},
setup: function () {
var store = BI.useStore(function () {
return BI.Models.getModel("demo.model");
});
setInterval(function () {
store.toggle();
}, 1000);
return function () {
return {
type: "bi.vertical",
vgap: 20,
items: [{
type: "demo.child"
}, {
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>

68
dist/fix/fix.compact.js vendored

@ -183,6 +183,74 @@
needPop && popTarget(); 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" && this._store) {
// 自动更新模式
var childComponents = {};
var rendered = false;
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 = childComponent.component.shouldUpdate && childComponent.component.shouldUpdate(nextProps);
childComponent.component._update(nextProps, shouldUpdate);
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; var unMount = BI.Widget.prototype.__d;
BI.Widget.prototype.__d = function () { BI.Widget.prototype.__d = function () {
try { try {

5
src/base/single/button/button.basic.js

@ -389,11 +389,6 @@ BI.BasicButton = BI.inherit(BI.Single, {
return this.options.text; 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) { _setEnable: function (enable) {
BI.BasicButton.superclass._setEnable.apply(this, arguments); BI.BasicButton.superclass._setEnable.apply(this, arguments);
if (enable === true) { if (enable === true) {

6
src/base/single/button/buttons/button.js

@ -1,4 +1,3 @@
/** /**
* 文字类型的按钮 * 文字类型的按钮
* @class BI.Button * @class BI.Button
@ -44,7 +43,10 @@ BI.Button = BI.inherit(BI.BasicButton, {
BI.Button.superclass._init.apply(this, arguments); BI.Button.superclass._init.apply(this, arguments);
var o = this.options, self = this; var o = this.options, self = this;
if (BI.isNumber(o.height) && !o.clear && !o.block) { 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) { } else if (o.clear || o.block) {
this.element.css({lineHeight: o.height / BI.pixRatio + BI.pixUnit}); this.element.css({lineHeight: o.height / BI.pixRatio + BI.pixUnit});
} else { } else {

16
src/base/single/single.js

@ -192,6 +192,7 @@ BI.Single = BI.inherit(BI.Widget, {
setValue: function (val) { setValue: function (val) {
if (!this.options.readonly) { if (!this.options.readonly) {
this.options.value = val; this.options.value = val;
this.options.setValue && this.options.setValue(val);
} }
}, },
@ -199,11 +200,24 @@ BI.Single = BI.inherit(BI.Widget, {
return this.options.value; return this.options.value;
}, },
update: function (props, shouldUpdate) {
if (BI.isObject(shouldUpdate)) {
props = shouldUpdate;
}
if ("value" in props) {
this.setValue(props.value);
}
if ("text" in props) {
this.setText && this.setText(props.text);
}
},
destroyed: function () { destroyed: function () {
if (BI.isNotNull(this.showTimeout)) { if (BI.isNotNull(this.showTimeout)) {
clearTimeout(this.showTimeout); clearTimeout(this.showTimeout);
this.showTimeout = null; this.showTimeout = null;
} }
BI.Tooltips.remove(this.getName()); BI.Tooltips.remove(this.getName());
}, }
}); });
BI.shortcut("bi.single", BI.Single);

7
src/core/ob.js

@ -72,6 +72,9 @@
// 获得一个当前对象的引用 // 获得一个当前对象的引用
_initRef: function () { _initRef: function () {
if (this.options.__ref) {
this.options.__ref.call(this, this);
}
if (this.options.ref) { if (this.options.ref) {
this.options.ref.call(this, this); this.options.ref.call(this, this);
} }
@ -79,6 +82,10 @@
//释放当前对象 //释放当前对象
_purgeRef: function () { _purgeRef: function () {
if (this.options.__ref) {
this.options.__ref.call(null);
this.options.__ref = null;
}
if (this.options.ref) { if (this.options.ref) {
this.options.ref.call(null); this.options.ref.call(null);
this.options.ref = null; this.options.ref = null;

55
src/core/widget.js

@ -7,7 +7,7 @@
*/ */
!(function () { !(function () {
function callLifeHook(self, life) { function callLifeHook (self, life) {
var hook = self.options[life] || self[life]; var hook = self.options[life] || self[life];
if (hook) { if (hook) {
var hooks = BI.isArray(hook) ? hook : [hook]; var hooks = BI.isArray(hook) ? hook : [hook];
@ -32,7 +32,8 @@
baseCls: "", baseCls: "",
extraCls: "", extraCls: "",
cls: "", cls: "",
css: null css: null,
updateMode: "manual" // manual / auto
}); });
}, },
@ -73,8 +74,11 @@
shouldUpdate: null, shouldUpdate: null,
update: function () { update: null,
},
beforeUpdate: null,
updated: null,
beforeDestroy: null, beforeDestroy: null,
@ -223,26 +227,59 @@
* @private * @private
*/ */
_mount: function (force, deep, lifeHook, predicate) { _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; var self = this;
if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) { if (!force && (this._isMounted || !this.isVisible() || this.__asking === true || !(this._isRoot === true || (this._parent && this._parent._isMounted === true)))) {
return false; return false;
} }
lifeHook !== false && callLifeHook(this, "beforeMount"); lifeHook !== false && callLifeHook(this, "beforeMount");
this._isMounted = true; this._isMounted = true;
this._mountChildren && this._mountChildren();
BI.each(this._children, function (i, widget) { BI.each(this._children, function (i, widget) {
!self.isEnabled() && widget._setEnable(false); !self.isEnabled() && widget._setEnable(false);
!self.isValid() && widget._setValid(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"); lifeHook !== false && callLifeHook(this, "mounted");
this.fireEvent(BI.Events.MOUNT); this.fireEvent(BI.Events.MOUNT);
predicate && predicate(this); predicate && predicate(this);
return true;
}, },
_mountChildren: null, _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 () { isMounted: function () {
return this._isMounted; return this._isMounted;
}, },
@ -534,12 +571,12 @@
BI.Widget.context = context = contextStack.pop(); BI.Widget.context = context = contextStack.pop();
}; };
function pushTarget(_current) { function pushTarget (_current) {
if (current) currentStack.push(current); if (current) currentStack.push(current);
BI.Widget.current = current = _current; BI.Widget.current = current = _current;
} }
function popTarget() { function popTarget () {
BI.Widget.current = current = currentStack.pop(); BI.Widget.current = current = currentStack.pop();
} }

17
src/core/wrapper/layout.js

@ -268,19 +268,13 @@ BI.Layout = BI.inherit(BI.Widget, {
if (!child.shouldUpdate) { if (!child.shouldUpdate) {
return null; return null;
} }
return child.shouldUpdate(this._getOptions(item)) === true; return child.shouldUpdate(this._getOptions(item));
}, },
updateItemAt: function (index, item) { updateItemAt: function (index, item) {
if (index < 0 || index > this.options.items.length - 1) { if (index < 0 || index > this.options.items.length - 1) {
return; 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)]; var del = this._children[this._getChildName(index)];
delete this._children[this._getChildName(index)]; delete this._children[this._getChildName(index)];
this.options.items.splice(index, 1); this.options.items.splice(index, 1);
@ -367,7 +361,14 @@ BI.Layout = BI.inherit(BI.Widget, {
patchItem: function (oldVnode, vnode, index) { patchItem: function (oldVnode, vnode, index) {
var shouldUpdate = this.shouldUpdateItem(index, vnode); var shouldUpdate = this.shouldUpdateItem(index, vnode);
if (shouldUpdate === true || (shouldUpdate === null && !this._compare(oldVnode, vnode))) { var child = this._children[this._getChildName(index)];
if (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); return this.updateItemAt(index, vnode);
} }
}, },

Loading…
Cancel
Save