Flutter:如何在多个类中使用函数结果而不重复函数

问题描述 投票:0回答:1

我有一些包含依赖内容的页面,我使用多个获取请求从 API 中检索这些内容。

这里,

getClass()
getValue()
正在从另一个类调用API,返回future。

List<dynamic> pIds, ps;
apiStart() async {
  pageIds = new List();
  siteCls = await _baseApi.getClass(siteCName);
  siteCId = siteCls.data.classId.toString();

  pageCls = await _baseApi.getClass(pageCName);
  pageCId = pageCls.data.classId.toString();

  siteIns = await _baseApi.getValue(siteCId);
  pageIns = await _baseApi.getValue(pageCId);

  pageIds = getPageIds();
  pages = getPagesData();
}

List getPageIds() {
  //Doing some work here
  return pIds;
}

List getPagesData() {
  //Doing some work here
  return ps;
}

现在我想从其他/多个类访问“页面”等变量,而不重复使用这些函数。我怎样才能做到这一点?

更新:

这是示例代码。它返回“欢迎 test1!”。当我从

content = "test1";
中删除
apiStart()
时,返回“欢迎 h!”。使用
await
有问题吗?

class AppData {
  factory AppData() {
    return _singleton;
  }
  static final AppData _singleton = AppData._internal();
  AppData._internal() {
    print("Instance created App-Data");
  }

  BaseApi _baseApi = new BaseApi();

  var content = "hi";
  Future body() {
    return Future.value(content);
  }

  void apiStart() async{
    content = "test1";//OK when I put content here 
    print(content);

    _ids = await _baseApi.fetchIds();
    //Does not change when I put content here
    //I need to use await because I need ids for next function
    content = "test2";  
    print(content);

    //Doing some work with result and get ids as list
    List id = idList();
     
    _pages = await _baseApi.fetchPages(id[0]);
    //Doing some work with result and get page content
    contents = contentList();
  }
}

如果我执行如下操作,它将返回“test2”。但我不知道如何检查工作是否完成;我应该在函数末尾添加一个布尔变量并每秒检查一次吗?这样有效率吗?

Future body() {
  return Future.delayed(Duration(seconds: 10)).then((value) => content);
}

我在哪里运行单例

void main() {
  runApp(MyApp());
  AppData().apiStart();
}

我展示了这样的部分结果:

class ContentWidget extends StatefulWidget {
  ContentWidget({Key key}) : super(key: key);

  @override
  _ContentWidgetState createState() => _ContentWidgetState();
}

class _ContentWidgetState extends State<ContentWidget> {
  Future<dynamic> futureContent;

  @override
  void initState() {
    super.initState();
    
    futureContent = AppData().body();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<dynamic>(
      future: futureContent,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return Text("Welcome ${snapshot.data}!", style: plainTextStyle);
        } else {
          //return Text("Welcome ${snapshot.error}!", style: plainTextStyle);
        }
        // By default, show a loading spinner.
        return CircularProgressIndicator();
      },
    );
  }
}
flutter dart async-await future
1个回答
0
投票

您可以使用单例模式来创建服务类:它使您可以从代码中的任何位置访问此类。

不要过度使用它,因为它可能会变成非常混乱的全局变量,例如缺乏封装。

注意:这是一个巨大的简化,但会起作用。阅读有关单例和服务的内容以了解更多信息。

class ApiService {
  // next 5 lines is a typical singleton pattern
  static ApiService _singleton;
  factory ApiService() {
    return _singleton ??= new ApiService._internal();
  }
  ApiService._internal();

  //here you'll keep your data
  List<dynamic> pageIds, pages; //store your data in these variables

  //run this on the beginning of your app to get your data. Don't forget this!
  void apiStart() async {
    // your code here where you hit the API and get all your data,
    // eg methods getPageIdsFromAPI and getPagesDataFromAPI that you need to write. They return your data
    //    pageIds = getPageIdsFromAPI();
    //    pages = getPagesDataFromAPI();
  }
}

然后从代码中的任何位置,您都可以访问此类中的变量和函数

ApiService().pageIds
ApiService().pageIds.length
ApiService().pageIds.contains(some_id)

---编辑---

您需要决定何时进行等待。要么在显示屏幕之前等待数据,要么以空/等待模式显示屏幕(就像 facebook 那样)然后等待。

做第二个:

@override
void initState() { 
  WidgetsBinding.instance.addPostFrameCallback((_) { 
    futureContent = await AppData().body();
    setState(() { 
      // refresh whatever changed. it's a good practice to specify what 
    });
  });
}
© www.soinside.com 2019 - 2024. All rights reserved.