diff --git a/README.md b/README.md index ffff14e..c8dd63c 100644 --- a/README.md +++ b/README.md @@ -38,3 +38,4 @@ FineUI 100个问题题,带你走进FineUI的世界 - [14、BI.config的执行顺序是什么,为什么这么设计](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/10.BI.config的执行顺序是什么,为什么这么设计.md) - [15、combo的一些特性详解](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/80.combo的一些特性详解.md) - [16、利用响应式编写组件代码的新思路](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/43.利用响应式编写组件代码的新思路.md) +- [17、如何提供异步配置的接口](https://code.fanruan.com/dailer/FineUI-100-Questions/src/branch/master/questions/44.如何提供异步配置的接口.md) diff --git a/images/18.gif b/images/18.gif new file mode 100644 index 0000000..e8d95dc Binary files /dev/null and b/images/18.gif differ diff --git a/images/19.gif b/images/19.gif new file mode 100644 index 0000000..860cd98 Binary files /dev/null and b/images/19.gif differ diff --git a/questions/44.如何提供异步配置的接口.md b/questions/44.如何提供异步配置的接口.md new file mode 100644 index 0000000..0174815 --- /dev/null +++ b/questions/44.如何提供异步配置的接口.md @@ -0,0 +1,150 @@ +# 如何提供异步配置的接口 + +回顾一下我们常用的提供拓展接口方式 + +1. 定义privider +2. 在被拓展的组件中调用`BI.Providers.getProvider().xxx` +3. 开发者通过`BI.config(xxx,privider => provider.inject())`注册 + +我们提供的配置接口,绝大多数时候都要求BI.config 要在资源加载前执行 +但是有些时候,插件资源是异步加载到,配置代码要异步执行,该如何设计接口? + +![示例](../images/18.gif) + +这里分享一个利用响应式特性开放异步接口的方式,核心思路是将拓展数据定义为响应式的,然后组件层采用响应式写法 + + +首先我们在Provider中定义响应式数据 + +```js +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提供的数据即可 +```js +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()`这种写法) +```js +BI.config("demo.provider.menus", provider => { + setTimeout(() => { + provider.inject({ + type: "bi.button", + text: "第三个", + }); + }, 4000); +}); +``` + +最终的效果呈现 + +![示例](../images/19.gif) + +```demo +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; + +``` \ No newline at end of file