首页 > 解决方案 > 是否可以将模型名称作为变量输入 Future 或在 Flutter 的 Future 中使用回调?

问题描述

背景

我理解 JS 回调的概念。在颤振的第 5 天,我完全不了解 dart/颤振中与回调的相互作用。

所以请多多包涵

我想要完成的事情

我正在尝试构建一组可重用的代码,这些代码可以从我的应用程序通信到 JSON 站点,以通过相同的确切代码库发出各种不同的 JSON 请求

我现在拥有的

我有一个 Future 调用,它成功地轮询一个站点以获取 JSON 数据并使用特定模型将其发送出去进行解析。

          Future<Result> getJSONfromTheSite(String thecall) async {
            try {
              //2
              final response = await client.request(requestType: RequestType.GET,
                  path: thecall).timeout(const Duration(seconds: 8));
              if (response.statusCode == 200) {
                //3
                return Result<MyModel>.success(MyModel.fromRawJson(response.body));
              } else {
                return Result.error(title:"Error",msg:"Status code not 200", errorcode:1);
              }
            } catch (error) {
                 (...)
            }
          }

我正在通过我的 UI 页面发出请求,如下所示:

FutureBuilder(
                future: _apiResponse.getJSONfromTheSite('latestnews'),
                builder: (BuildContext context, AsyncSnapshot<Result> snapshot) {
              if (snapshot.data is SuccessState) { ...

使用我在各种 UI 页面上从 FutureBuilder 输入的变量thecall,我可以成功更改正在发出的 http JSON 请求以轮询不同的数据。

我坚持什么

我陷入困境的地方是,虽然我可以成功地改变请求以更改我正在轮询的数据,但我无法对结果做任何事情,因为我当前的代码总是想用来MyModel解析 JSON。

return Result<MyModel>.success(MyModel.fromRawJson(response.body));

问题

我基本上需要能够根据发出请求的 UI 页面来切换针对此 JSON 数据使用的模型,而不是对相同代码的 10 个版本进行硬编码。

我正在考虑通过 FutureBuilder 调用输入我想用于该特定调用的模型的名称。例如类似的东西,future: _apiResponse.getJSONfromTheSite('latestnews', MyModel2),但那根本不起作用。
或者,我正在考虑将整个return Result<MyModel>.success(MyModel2.fromRawJson(response.body));作为回调发送。

回调的概念在我的 JS 时代是有意义的,但我不确定我是否在这里正确应用了这个概念。因此,如果我以错误的方式解决这个问题,我会全力以赴地寻求更优雅的解决方案。

谢谢!

标签: flutterdart

解决方案


您可以简单地将要使用的构造函数作为回调传递,并使您的方法getJSONfromTheSite动态类型化。唯一的问题是您将无法定义fromRawJson为工厂构造函数,而是定义为返回对象实例的静态方法。

代码示例

// Your method fromRawJson should be implemented like this
class MyModel {
  // ...

  static MyModel fromRawJson(Map<String, dynamic> json) =>
      MyModel(/* your parameters */);
}

/// T is the dynamic type which you will use to define if it is
/// MyModel or any other class.
Future<Result<T>> getJSONfromTheSite<T>(
  String thecall,
  T Function(Map<String, dynamic>) jsonFactory,
) async {
  try {
    // ...

    return Result<T>.success(jsonFactory(response));
  } catch (error) {
    // ...
  }
}

// Then you can call your method like this
await getJSONfromTheSite<MyModel>('latestnews', MyModel.fromRawJson);

// For another class such as MyModel2 it would be like this
await getJSONfromTheSite<MyModel2>('', MyModel2.fromRawJson);

在 DartPad 上试用完整代码


推荐阅读