# combo一些不为人知的特性 ## combo的trigger属性是可以设置为空的 去掉combo的默认弹出事件,手动控制showView,在某些场景中很有用.例如需要控制有些场景要弹出,有些场景不要弹出. 例如BI业务中有一个场景,叫做"开启权限继承后气泡提示" ![示例](../../../images/17.gif) ```demo let combo; let switchBtn; BI.createWidget({ type: "bi.bubble_combo", ref: (ref) => combo = ref, el: { type: "bi.switch", ref: (ref) => switchBtn = ref, handler: () => { switchBtn.isSelected() ? combo.showView() : combo.hideView(); }, }, trigger: "", popup: { el: { type: "bi.label", text: "提示文字", }, }, }); ``` 另一个场景,有些提示文本提示一次后不再提示, ```demo let combo; BI.createWidget({ type: "bi.vertical", items: [ { type: "bi.combo", ref: ref => combo = ref, trigger: "", el: { type: "bi.button", text: "触发弹出", handler: () => { if (BI.Cache.getItem("confirmed")) { combo.showView(); return; } BI.Msg.confirm("弹出是手动的,你知道吧", confirmed => { if (confirmed) { BI.Cache.setItem("confirmed", true); combo.showView(); } }); }, }, popup: { el: { type: "bi.label", text: "popup", }, }, }, ], }); ``` ## combo的popup是在弹出时候创建的,但是props却是在combo创建时候确定的 应对这种情况,常见的解决方案是`isDefaultInit: true`或者将popup属性改为函数 注意设置了`isDefaultInit: true`后会有响应的性能或体验损失 ```demo BI.createWidget({ type: "bi.vertical", items: [ { type: "bi.combo", el: { type: "bi.label", text: BI.getDate(), }, popup: { el: { type: "bi.label", text: BI.getDate(), }, }, }, { type: "bi.combo", el: { type: "bi.label", text: BI.getDate(), }, isDefaultInit: true, popup: { el: { type: "bi.label", text: BI.getDate(), }, }, }, { type: "bi.combo", el: { type: "bi.label", text: BI.getDate(), }, popup: () => ({ el: { type: "bi.label", text: BI.getDate(), }, }), }, ], }); ``` ## combo的value传递和getValue很奇怪 在多数场景中,给bi.combo传递value属性,可以使下拉框在展开时候自动选中某一项.前提是popup的el组件支持value属性 如下的combo,value是不生效的.需要对bi.button_group传递value属性 同样的,如果在展开之前value可能发生改变,要注意value的同步 ```demo var Combo = BI.inherit(BI.Widget, { render: function () { return { type: "bi.combo", el: { type: "bi.label", }, ref: ref => this.combo = ref, value: this.options.value, popup: { el: { type: "bi.vertical", items: [ { type: "bi.button_group", layouts: [ { type: "bi.vertical", }, ], items: [ { type: "bi.single_select_radio_item", text: "1", value: 1, }, { type: "bi.single_select_radio_item", text: "2", value: 2, }, ], }, ], }, }, }; }, getValue: function () { return this.combo.getValue(); }, setValue: function (v) { this.combo.setValue(v); }, }); BI.shortcut("demo.combo", Combo); ``` ## destroyWhenHide 当控制下拉框的状态比较复杂的时候,可以通过收起时候销毁再重新创建来简化 例如消息下拉框,内部两个独立的业务组件,一个展示消息列表,一个展示二维码.希望每次弹出都能重新加载消息.配置destroyWhenHide可以完全交友message_list 的生命周期去控制,避免了监听combo弹出事件,在命令式调用刷新逻辑. ```demo BI.createWidget({ type: "bi.vertical", items: [ { type: "bi.combo", ref: ref => combo = ref, trigger: "", el: { type: "bi.button", text: "触发弹出", }, destroyWhenHide: true, popup: { el: { type: "bi.vertical", items: [ { type: "message_list", }, { type: "qr_code", }, ], }, }, listeners: [ { eventName: BI.Combo.EVENT_AFTER_POPUPVIEW, action: function () { // do something }, }, ], }, ], }); ``` ## hideWhenBlur 先说怎么屏蔽这个行为,再说为什么设计这个属性 1. 全局变量`BI.EVENT_BLUR`改为`false` 2. combo配置`hideWhenBlur: false` 为什么要添加这一个特性呢,实际上是因为iframe会隔离事件的缘故,下拉框弹出后,鼠标在iframe中操作并不会触发外部的`document.mousedown` 因此下拉框也就无法收起了. 以前是怎么处理呢,`trigger: "click-hover"`,即点击触发弹出,鼠标移除触发收起,但是体验差点意思 ![](../../../images/2.png)