You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

6.6 KiB

combo一些不为人知的特性

combo的trigger属性是可以设置为空的

去掉combo的默认弹出事件,手动控制showView,在某些场景中很有用.例如需要控制有些场景要弹出,有些场景不要弹出.

例如BI业务中有一个场景,叫做"开启权限继承后气泡提示"

示例 示例

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: "提示文字",
        },
    },
});

另一个场景,有些提示文本提示一次后不再提示,


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后会有响应的性能或体验损失


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的同步


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弹出事件,在命令式调用刷新逻辑.


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",即点击触发弹出,鼠标移除触发收起,但是体验差点意思