在哪里调用Web服务来获取Flutter Widget中的数据?

时间:2018-04-06 07:45:41

标签: dart flutter

我有以下屏幕:

import 'package:flutter/material.dart';
import '../models/patient.dart';
import '../components/patient_card.dart';
import '../services.dart';

class Home extends StatefulWidget {
  var patients = <Patient>[];

  @override
  _HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {
  @override
  initState() {
    super.initState();
    Services.fetchPatients().then((p) => setState(() => widget.patients = p));
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Home'),
      ),
      body: new Container(
        child: new ListView(
          children: widget.patients.map(
            (patient) => new PatientCard(patient),
          ).toList()
        )
      )
    );
  }
}

正如您所看到的,当我覆盖initState()中的_HomeState时,我会执行端点调用。但它最初只在应用程序启动时运行一次。我不能只在终端中输入r并让应用程序热重新加载并再次调用端点..我必须先使用Shift + r进行完全重启。

所以问题是,我是否在推荐的地点呼叫网络服务?如果不是......它会去哪里?此外,ListView不应该有一个函数/属性被调用“拉动刷新”或什么?

3 个答案:

答案 0 :(得分:1)

如@aziza所述,您可以使用Stream Builder,或者如果您想在每次构建小部件时调用函数,那么您应该在构建函数本身中调用它。就像你的情况一样。

@override
Widget build(BuildContext context) {
Services.fetchPatients().then((p) => setState(() => widget.patients = p));
return new Scaffold(
  appBar: new AppBar(
    title: new Text('Home'),
  ),
  body: new Container(
    child: new ListView(
      children: widget.patients.map(
        (patient) => new PatientCard(patient),
      ).toList()
    )
  )
);

}

如果您想添加pull-to-refresh功能,请将您的小部件包装在refresh indicator小部件中。在onRefresh属性中添加您的电话。

return new RefreshIndicator(child: //Your Widget Tree,
                            onRefresh: handleRefresh);

请注意,此小部件仅适用于垂直滚动视图。

希望它有所帮助。

答案 1 :(得分:0)

查看StreamBuilder。此小组件允许您处理经常更新的异步数据,并通过在流末尾监听onValue来相应地更新UI。

答案 2 :(得分:0)

Flutter有FutureBuilder类,你也可以创建你的小部件,如下所示

Widget build(BuildContext context) {
    var futureBuilder = new FutureBuilder(
        future: Services.fetchPatients().then((p) => setState(() => widget.patients = p)),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            if (snapshot.data != null) {
              return new Container(
                  child: new ListView(
                      children: snapshot.data.map(
                            (patient) => new PatientCard(patient),
                      ).toList()
                  )
              );
            }
          } else {
            return new Container(
                alignment: Alignment.center,
                padding: const EdgeInsets.all(16.0),
                child: new CircularProgressIndicator());
          }
        });
    return new Container(child: futureBuilder);
  }

示例项目:Flutter - Using the future builder with list view.