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.
 

3.2 KiB

如何提供异步配置的接口

回顾一下我们常用的提供拓展接口方式

  1. 定义privider
  2. 在被拓展的组件中调用BI.Providers.getProvider().xxx
  3. 开发者通过BI.config(xxx,privider => provider.inject())注册

我们提供的配置接口,绝大多数时候都要求BI.config 要在资源加载前执行 但是有些时候,插件资源是异步加载到,配置代码要异步执行,该如何设计接口?

示例

这里分享一个利用响应式特性开放异步接口的方式,核心思路是将拓展数据定义为响应式的,然后组件层采用响应式写法

首先我们在Provider中定义响应式数据

const Provider = function () {

    const state = Fix.define({
        menus: [],
    });

    this.inject = function (menu) {
        state.menus.push(menu);
    };

    this.$get = function () {
        return BI.inherit(BI.OB, {
            getMenus: () => {
                return state.menus.slice(0);
            },
        });
    };

};
BI.provider("demo.provider.menus", Provider);

之后再组件中通过函数响应式使用provider提供的数据即可

const Menus = function () {

    const getMenuItems = function () {
        return BI.Providers.getProvider("demo.provider.menus").getMenus();
    };

    const defaultMenus = [
        {
            type: "bi.button",
            text: "第一个",
        }, {
            type: "bi.button",
            text: "第二个",
        },
    ];

    return {
        type: "bi.vertical",
        items: () => BI.concat(defaultMenus, getMenuItems()),
    };
};

开发者依然通过同步的方式调用BI.config,但是配置函数却可以是异步的 (思考一下为什么不是setTimout(() => BI.config()这种写法)

BI.config("demo.provider.menus", provider => {
    setTimeout(() => {
        provider.inject({
            type: "bi.button",
            text: "第三个",
        });
    }, 4000);
});

最终的效果呈现

示例

const Provider = function () {

    const state = Fix.define({
        menus: [],
    });

    this.inject = function (menu) {
        state.menus.push(menu);
    };

    this.$get = function () {
        return BI.inherit(BI.OB, {
            getMenus: () => {
                return state.menus.slice(0);
            },
        });
    };

};
BI.provider("demo.provider.menus", Provider);

const Menus = function () {

    const getMenuItems = function () {
        return BI.Providers.getProvider("demo.provider.menus").getMenus();
    };

    const defaultMenus = [
        {
            type: "bi.button",
            text: "第一个",
        }, {
            type: "bi.button",
            text: "第二个",
        },
    ];

    return {
        type: "bi.vertical",
        items: () => BI.concat(defaultMenus, getMenuItems()),
    };
};

BI.config("demo.provider.menus", provider => {
    setTimeout(() => {
        provider.inject({
            type: "bi.button",
            text: "第三个",
        });
    }, 4000);
});


const Widget10 = BI.createWidget({
    type: "bi.vertical",
    items: [
        {
            el: Menus(),
        },
    ],
});

return Widget10;