我如何使用提供程序获取异步数据? (颤振)

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

背景

我正在构建用于练习Flutter的超级简单的TODO列表应用。如果输入字符串并单击“添加”,则文本将显示在上部的列表中。

问题

[何时以及如何调用model.getTasks()(=异步更新数据)和model.refresh()(= notifyListeners)?

我发现列表没有立即更新,因为我没有将await用作model.getTasks()。我尝试了这些,但是我想知道是否有更好的方法。

  • 使用await model.getTasks()并使build为异步功能。 ->编译错误
  • await model.getTasks()之前添加model.refresh()。 ->打开应用程序时,在渲染model.tasks之前不会更新ListView。创建新任务时,会两次调用model.getTasks()

截图

App TODO list page

代码详细信息

  • [model.tasksList<Task>,用于存储从数据库(sqflite)中提取的任务。
  • [model.getTasks()是一个异步函数,用于从数据库中获取数据并覆盖model.tasks
  • [model.refresh()仅用于调用notifyListeners()
  • [TodoListPage是模型的notifyListeners的侦听器。
class TodoListPage extends StatelessWidget {
  final TextEditingController _textFieldController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    print('TodoListPage.build');
    final model = Provider.of<TodoListModel>(context);
    model.getTasks();

    Future createTask() async {
      TaskData taskData = await DatabaseHandler()
          .insertTask(new TaskData(name: _textFieldController.text));
      model.refresh();
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(
          'TODO List',
        ),
      ),
      body: Column(
        children: <Widget>[
          Container(
            height: 150,
            child: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return Text(model.tasks[index].name);
              },
              itemCount: model.tasks.length,
            ),
          ),
          Text(
            'Add',
          ),
          Form(
            child: Column(
              children: <Widget>[
                TextFormField(
                  controller: _textFieldController,
                ),
                RaisedButton(
                  onPressed: () {
                    print('onPressed');
                    print(_textFieldController.text);
                    createTask();
                  },
                  child: Text('New'),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}
flutter provider sqflite
1个回答
0
投票

您可以在FutureBuilder中使用StatefulWidget

class TodoListPage extends StatefulWidget {
  @override 
  _TodoListPageState createState() => _TodoListPageState();
}

class _TodoListPageState extends State<TodoListPage> {
  TodoListModel model;
  Future<List<Tasks>> _getTasks;

  @override
  void didChangeDependencies() {
    model = Provider.of<TodoListModel>(context);
    _getTasks = model.getTasks();
  }

  @override
  Widget build() {
    FutureBuilder<List<Tasks>>(
      future: _getTasks,
      builder: (context, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return Text("Loading tasks...");
        }

        final tasks = snapshot.data;

        // ...
      }
    );
  }
}

在您的模型中:

Future<List<Tasks>> getTasks() async {
  if (tasks == null) {
    tasks = await loadFromDatabase();
  }

  return tasks;
}
© www.soinside.com 2019 - 2024. All rights reserved.