Как получить индивидуальное значение из базы данных с помощью Moor_Flutter - PullRequest
0 голосов
/ 10 января 2020

У меня есть страницы настроек, которые используют очень простую базу данных, которая состоит из пары таблиц, чтобы изменить внешний вид карты Google (google_maps_flutter). Есть еще одна таблица, но она используется для чего-то другого в приложении, и я не занимаюсь этим здесь. Я использую для этого пакеты moor_flutter и провайдера, но у меня возникают небольшие трудности с возвратом значения.

Что я хочу сделать, это получить логическое значение (в данном случае) и соответственно отобразить SwitchListTile, но, к сожалению, я могу получить эту ошибку.

NoSuchMethodError: У класса 'List' нет экземпляров getter 'tilt'. Получатель: Экземпляр (длина: 0) из _GrowableList. Пробный вызов: наклон. См. Также: https://flutter.dev/docs/testing/errors

Любая помощь будет оценена.

Вот мой конфиг таблицы

// Map Parameters table definition
class Parameters extends Table {
  BoolColumn get tilt => boolean().withDefault(Constant(true))();
  BoolColumn get traffic => boolean().withDefault(Constant(false))();
  BoolColumn get compass => boolean().withDefault(Constant(true))();
  BoolColumn get rotate => boolean().withDefault(Constant(true))();
  BoolColumn get zoom => boolean().withDefault(Constant(true))();
  /*TextColumn get type => text().named('normal')();
  TextColumn get area => text().named('Uni Campus')();*/
}

Вот мой Класс AppDatabase

// App Database Class
@UseMoor(
    tables: [Parameters, Themes, Places],
    daos: [ParameterDao, ThemeDao, PlaceDao])
class AppDatabase extends _$AppDatabase {
  AppDatabase()
      : super(FlutterQueryExecutor.inDatabaseFolder(
            path: 'db.sqlite', logStatements: true));

  // Database Schema Version
  @override
  int get schemaVersion => 1; // Change this with every DB change

  @override
  MigrationStrategy get migration => MigrationStrategy(
    onUpgrade: (migrator, from, to) async{
      if(from == 1){
        // await migrator.addColumn(<table, <table>.<fieldName>);
        // await migrator.createTable(<table>);
      }
    },
    /*beforeOpen: (db,details) async {
      await db.customStatement('PRAGMA foreign_keys = ON');
    }*/
  );
}

Вот мой класс Dao

@UseDao(tables: [Parameters])
class ParameterDao extends DatabaseAccessor<AppDatabase> with _$ParameterDaoMixin {
  final AppDatabase db;

  ParameterDao(this.db) : super(db);

  // Map parameters queries
  Future<List<Parameter>> getAllParameters() => select(parameters).get();
  Stream<List<Parameter>> watchAllParameters() => select(parameters).watch();
  Future updateParameter(Parameter parameter, {bool tilt}) =>
      update(parameters).replace(parameter);
}

Вот виджет, который содержит мою страницу настроек

@override
  Widget build(BuildContext context) {
    final dao = Provider.of<ParameterDao>(context);
    return StreamBuilder(
        stream: dao.watchAllParameters(),
        builder: (context, AsyncSnapshot snapshot) {
          bool _allowTilt = snapshot.data.tilt;
          bool _enableRotate = true;
          bool _enableZoom = true;
          bool _showTraffic = false;
          bool _showCompass = true;
          return Container(
            child: DecoratedBox(
              decoration: BoxDecoration(
              ...
              ...
              ...

, а вот мой SwitchListTile

SwitchListTile(
    value: _allowTilt,
    onChanged: (value) {
        setState(() {
            // _allowTilt = value;
            //_db.updateParameter(tilt: _allowTilt);
            //print("ALLOW TILT => _allowTilt");
        });
    },
    title: Text(
        AppLocalizations.of(context).settingsLabelTilt),
    activeColor: Theme.UniColour.primary[900],
 ),

1 Ответ

1 голос
/ 10 января 2020

Это bool _allowTilt = snapshot.data.tilt; строка, которая вызывает ошибку?

Поскольку похоже, что вы пытаетесь получить доступ к свойству tilt в snapshot.data, но data должно быть List в соответствии с вашим DAO.

DAO возвращает Stream<List<Parameter>>, поэтому ваш data разворачивается в List<Parameter>.

Если в таблице есть только одна запись, к которой вы можете получить доступ запись, вызвав first в списке, или вы позвоните watchSingle() в своем DAO, чтобы вы получили только одну запись (сгенерирует исключение, если в таблице более одной записи). Или вам нужно l oop вместо data.

Кстати, data может быть null, и это хорошая идея, чтобы проверить, если snapshot.hasData, прежде чем получить доступ к data .

...