连载第十四期
《高级指引:Use Resolves》
▽
useResolves 是构件生命周期的重要特性,它扮演着类似 Angular Router 的 Resolve 角色。它主要解决构件初始化需要的异步数据请求,简化构件编写的代码量,并且使平台统一解决相关加载状态和错误反馈成为了可能。
⊙NOTE
现在更推荐通过在路由上定义 Context 上下文来处理异步数据,以实现更高效的请求并发。
# 示例
如下的构件配置,平台在渲染该构件前,将首先调用useProvider 指定的 Provider 构件的 resolve() 方法,并使用指定的 args 参数,请求完成时,将使用 name 指定的属性名赋值给该构件。平台将确保构件渲染前获得该属性,因此构件不再需要对该数据请求处理加载状态及错误反馈,这些将由平台统一处理。
bricks:
- brick: your.awesome-brick
lifeCycle:
useResolves:
- useProvider: your.awesome-provider
args: ["${someQueryParam}"]
name: someProp
在早期版本中,我们只提供了通过 provider 指定CSS Selector 并需提前在 bricks 或 providers 中主动声明对应的 Provider 构件的方式来使用 useResolves,例如以下的构件配置,平台在渲染该构件前,将首先找到 provider 匹配的对应的 Provider 构件,然后执行它的 resolve() 方法,并使用指定的 args 参数,请求完成时,将使用 name 指定的属性名赋值给该构件。
bricks:
- brick: micro-app-store.provider-app-detail
bg: true
args:
- "${appId}"
- brick: micro-app-store.micro-app-detail
lifeCycle:
useResolves:
- name: appDetail
provider: micro-app-store\.provider-app-detail
现在我们更推荐使用 useProvider,因为它相比于早期的 provider 字段具有以下优势:
- 使用构件名,无需对构件名中的点号 . 进行转义;
- 不需要在 bricks 或 providers 中提前声明该构件。
useProvider 即用即取、无状态,如果希望在分步更新参数等场景下使用,可以结合 Context 上下文来处理。
注意
- useProvider 字段为 Provider 的构件名。
- provider 字段为 Css Selector,因此构件名称中的 . 需要转义。
- 使用 provider 字段时,对应的 Provider 构件在 bricks 列表中需要指定 bg: true 才能正常工作。
通过平台提供的脚手架工具 yarn yo 或封装的方法 createProviderClass 可以快速创建 Provider 构件,请参考 Provider 构件的创建。
# 配置说明
useResolves 有两种模式:
普通配置模式:
注意:useProvider 和 provider 应选取且只选取一种,它们的差别在本文上一章节有描述。
使用 ref 模式:
其中 args 参数有多种来源:
- 优先使用 useResolves 配置中的 args,它支持和属性配置一致的模板字符串,并且默认启用 injectDeep: true。
- 其次使用 Provider 构件的 args 属性,它可以通过 Provider 构件的 properties 等方式设置。
注意:templates 也可以使用 useResolves,只不过取得的数据将传递给 params 而不是 properties。
# defineResolves
在Storyboard 的路由配置中,可以使用defineResolves预定义一些resolves 以供 useResolves 引用。例如:
# Route
path: "/index",
defineResolves:
- id: "cmdb-model-list"
provider: "cmdb.get-object-list"
args:
- pageSize: 3000
field: "data.list"
在构件中可以这样使用:
# Brick
brick: "your-brick",
lifeCycle:
useResolves:
- name: "cmdbModelList"
ref: "cmdb-model-list"
#配置说明
defineResolves 与 useResolves 的普通配置模式上大体相似,主要有以下不同:
- defineResolves 必须声明一个 id。
- defineResolves 不能声明属性名 name。
- defineResolves 中的 transform 不再有「转换成属性」的用途,而是「给 useResolves 提供数据源」的作用。
# 请求异常处理 onReject
通常不需为 useResolves 设置异常处理,因为系统会统一捕获并显示错误信息。由于 useResolves 请求的数据定义为页面依赖的必要数据,因此页面加载过程中任何 useResolves 出现错误将使整个页面停止加载并显示对应的错误信息。
有时候我们期望某些构件的某些请求错误可以不影响页面中其它构件的渲染,此时我们可以设置 onReject 对请求错误进行特殊处理。
方式一:设置 onReject: { transform: ... } 进行数据转换后重新赋值给构件的相关属性,此时转换的数据源为该错误对象。此方法适用于支持空状态(错误状态)的属性配置的构件。
方式二:设置 onReject: { isolatedCrash: true } 使用系统提供的一个报错构件替代原构件,并显示对应的报错信息。此方法适用于不支持空状态(错误状态)的属性配置的构件。