直接跳到内容

网络父类

介绍

网络父类用于处理“单次请求”的通用场景,把加载、错误、成功这三种状态统一封装起来。页面只关心成功后怎么展示数据,其它状态交给框架处理。

使用流程

  1. ViewModel 继承 BaseNetWorkViewModel 并实现 requestRepository()
  2. 页面使用 BaseNetWorkView,根据 uiState 渲染内容。
  3. 失败时调用 retryRequest() 重新发起请求。

UI 状态

BaseNetWorkUiState 有三种状态:

  • LOADING:加载中
  • SUCCESS:请求成功
  • ERROR:请求失败

BaseNetWorkViewModel API

文件位置:core/base/src/main/ets/viewmodel/BaseNetWorkViewModel.ets

说明:T 为请求成功后的数据类型,对应仓库返回的业务实体。例如请求商品详情时,T 就是 Goods

属性

属性说明类型默认值
uiState当前请求状态BaseNetWorkUiStateLOADING
data请求成功后的数据T | nullnull
showErrorToast是否展示失败提示booleanfalse

方法

方法说明参数返回值
requestRepository()子类实现,返回请求 Promise-Promise<NetworkResponse<T>>
executeRequest()发起请求-void
retryRequest()重试请求-void
onRequestStart()请求开始前回调-void
onRequestSuccess(data)请求成功回调data: Tvoid
onRequestError()请求失败回调-void

BaseNetWorkView API

文件位置:core/ui/src/main/ets/component/network/BaseNetWorkView.ets

参数

参数说明类型默认值
uiState当前请求状态BaseNetWorkUiStateLOADING
onRetry失败后的重试回调() => void空函数
loadingBuilder自定义加载视图CustomBuilder
errorBuilder自定义错误视图CustomBuilder
content成功状态内容CustomBuilder

使用示例

下面示例基于项目里的网络请求 Demo,展示 ViewModel 和页面的标准写法。

ViewModel

ts
import { BaseNetWorkViewModel } from "base";
import { GoodsRepository } from "data";
import { Goods, NetworkResponse } from "model";

/**
 * @file Network Demo 示例页 ViewModel
 */
@ObservedV2
export default class NetworkDemoViewModel extends BaseNetWorkViewModel<Goods> {
  /**
   * 商品仓库
   */
  private repository: GoodsRepository = new GoodsRepository();

  /**
   * 请求商品详情数据
   * @returns {Promise<NetworkResponse<Goods>>} 网络请求 Promise
   */
  protected requestRepository(): Promise<NetworkResponse<Goods>> {
    return this.repository.getGoodsInfo("1");
  }
}

页面

ts
import { ColumnCenter } from "designsystem";
import { AppNavDestination, BaseNetWorkView } from "ui";
import NetworkDemoViewModel from "../viewmodel/NetworkDemoViewModel";

/**
 * @file Network Demo 示例页视图
 */
@ComponentV2
export struct NetworkDemoPage {
  /**
   * Network Demo 示例页 ViewModel
   */
  @Local
  private vm: NetworkDemoViewModel = new NetworkDemoViewModel();

  /**
   * 构建 Network Demo 示例页
   * @returns {void} 无返回值
   */
  build() {
    AppNavDestination({
      title: $r("app.string.demo_base_network_title"),
      viewModel: this.vm
    }) {
      BaseNetWorkView({
        uiState: this.vm.uiState,
        onRetry: (): void => this.vm.retryRequest(),
        content: (): void => this.NetworkDemoContent()
      });
    }
  }

  /**
   * 构建网络示例内容
   * @returns {void} 无返回值
   */
  @Builder
  private NetworkDemoContent() {
    ColumnCenter() {
      Text(this.vm.data?.title ?? "");
      Text(this.vm.data?.subTitle ?? "");
    }
  }
}

注意事项

  • 页面需要用 BaseNetWorkView 包住内容,才能根据状态切换加载、错误和成功视图。
  • 不要在页面里直接发请求,统一放在 ViewModel 中处理。