Флаттер Future & Sqflite - PullRequest
       67

Флаттер Future & Sqflite

0 голосов
/ 17 февраля 2020

Я использую Sqflite для сохранения данных (например, имя человека). С помощью этой функции я получаю данные БД:

Future<List<Student>> getStudentList() async {
await openDb();
final List<Map<String, dynamic>> maps = await _database.query('student', orderBy: 'name ASC'); 
return List.generate(maps.length, (i) {
  return Student(
      id: maps[i]['id'], name: maps[i]['name']);
});
}

В начале я хочу добавить имена в БД в список.

  @override
void initState() {
foo();
//userList.add(User('Test1', 'Test, false));
//userList.add(User('test2', 'test', false));
userList
    .sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
filterList();
searchController.addListener(() {
  filterList();
});
super.initState();
}

Вот как я определил foo (), где я хочу получить данные из БД:

Future foo() async{ 
studlist = await dbmanager.getStudentList();
 var tl = studlist.length;
  for (var i = 0; i < tl; i++) {
  userList.add(User(studlist[i].name, 'Test', false));
  // print('${studlist[i].name}');
 // print('$i');
}
}

Проблема в том, что эта функция ничего не сохраняет в списке. Если я использую в void initState() этот тестовый код вместо foo (), он работает:

userList.add(User('Test1', 'Test, false));
userList.add(User('test2', 'test', false));

Так что с foo() что-то не так. Я также добавил print('${studlist[i].name}'); print('$i'); в for для l oop, чтобы проверить, работает ли studlist[i], и он напечатал каждое имя.

Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 17 февраля 2020

Проблема в том, что ваш foo метод asyn c, и вы его не ожидаете. Таким образом, код вызова initState возвращается, как только наступит ожидание и до того, как ваш userList добавится. В конце концов, добавление произойдет, но вы до запуска initState logi c работаете. Чтобы это работало, вам нужно дождаться завершения foo. Вы не можете просто go и сделать initState asyn c и ждать foo, но вы можете выполнить свою работу после завершения Future, используя метод then.

void initState() {
  foo().then((result) {
      userList
        .sort((a, b) => a.name.toLowerCase().compareTo(b.name.toLowerCase()));
    filterList();
    searchController.addListener(() {
      filterList();
    });
    setState(() => {});
  });

  super.initState();
}

Теперь ваш build должен будет обрабатывать случай загрузки, в котором у вас еще нет пользователей, но этот код должен заполнить ваш userList и перестроить ваш взгляд с пользователями. Если это становится более сложным, вы можете рассмотреть возможность использования StreamBuilder , который более удобен для работы с этим асин c поведением.

...