我正在Flitter中创建我的第一个应用程序,这个应用程序使用的是sqlite database.所以我有模型和存储库.

代码布局:

我有2个型号(将在完成的应用程序中有更多)UserModel,TimesheetModel,这两个都扩展了BaseModel

我有2个存储库(将在完成的应用程序中有更多)UserRepository,时间表,这两个都扩展到基本存储库

我想要做的是: 我希望在基本存储库中有可重用的代码,如:getAll()countAll()等,这样扩展基础存储库的所有存储库都具有此功能,我所需要做的就是设置表名并设置返回的Model.

错误是:

我不知道怎么解决这个问题,有什么建议吗?

基本存储库

abstract class 基本存储库 {
  final String table;
  final model;

  基本存储库({this.table, this.model});

  // Retrieve all the items
  Future<List<BaseModel>> all() async {
    final sql = '''SELECT * FROM $table''';
    final data = await db.rawQuery(sql);

    List<BaseModel> forms = List();
    for (final node in data) {
      final form = model.fromJson(jsonData: node);
      forms.add(form);
    }
    return forms;
  }

  // Find an item by its ID
  Future findById(int id) async {
    final sql = '''SELECT * FROM $table
    WHERE id = ?''';

    List<dynamic> params = [id];
    final data = await db.rawQuery(sql, params);

    final form = model.fromJson(jsonData: data.first);
    return form;
  }

  // Count all the items
  Future<int> count() async {
    final data = await db.rawQuery('''SELECT COUNT(*) FROM $table''');

    int count = data[0].values.elementAt(0);
    int idForNewItem = count++;
    return idForNewItem;
  }

  // clear the table
  Future<void> delete() async {
    // truncate current database table
    await db.rawQuery('''DELETE FROM $table''');
  }
}

时间表

class 时间表 extends 基本存储库 {
  String table = 'timesheets';
  TimesheetModel model = new TimesheetModel();

  // Search for a item by its name
  Future<List<TimesheetModel>> findByDate(DateTime dateTime) async {
    final String date = DateFormat("yyyy-MM-dd").format(dateTime);
    final sql = '''SELECT * FROM $table WHERE timesheet_date = ?''';
    List<dynamic> params = [date];

    final data = await db.rawQuery(sql, params);
    List<TimesheetModel> forms = List();

    for (final node in data) {
      final form = TimesheetModel.fromJson(jsonData: node);
      forms.add(form);
    }
    return forms;
  }

  // Add a new item
  Future<void> store(TimesheetModel timesheet) async {
    final sql = '''INSERT INTO $table
    (
      user_id,
      timesheet_date,
      start_time,
      end_time,
      json,
      is_uploaded
    )
    VALUES (?,?,?,?,?,?)''';

    List<dynamic> params = [
      timesheet.userId,
      DateFormat("yyyy-MM-dd").format(timesheet.timesheetDate),
      timesheet.startTime,
      timesheet.endTime,
      convert.json.encode(timesheet.json),
      timesheet.is_uploaded,
    ];

    final result = await db.rawInsert(sql, params);
    DatabaseCreator.databaseLog('Add form', sql, null, result, params);
  }


}

呼叫时间表上的全部时

时间表 timesheet = 时间表();
timesheet.all();

基础模型

abstract class BaseModel {
  fromJson();
}

时间表模型


class TimesheetModel extends BaseModel {
  int id;
  int userId;
  DateTime timesheetDate;
  String startTime;
  String endTime;
  Map json = {
    "task": "",
    "detail": "",
    "notes": "",
  };
  bool is_uploaded;

  TimesheetModel({
    this.id,
    this.userId,
    this.timesheetDate,
    this.startTime,
    this.endTime,
    this.json,
    this.is_uploaded,
  });


  fromJson({Map<String, dynamic> jsonData}) {

    return TimesheetModel(
      id: jsonData['id'] as int,
      userId: jsonData['user_id'] as int,
      timesheetDate: timesheetDate,
      startTime: jsonData['start_time'],
      endTime: jsonData['end_time'],
      is_uploaded: hasUploaded,
    );
  }
}

推荐答案

我不会像您这样从Json进行解析,因为您需要传递模型的空实例才能创建同一对象的有效实例.但是,为了让您的体系 struct 正常工作,您需要做一些修改:

1-使用泛型.

BaseRepository

abstract class BaseRepository<T extends BaseModel> {
  BaseRepository({this.table, this.model});

  final String table;
  final T model;

  // Retrieve all the items
  Future<List<T>> all() async {
    final sql = '''SELECT * FROM $table''';
    final data = await db.rawQuery(sql);

    return data.map((node) {
      return model.fromJson(jsonData: node);
    }).toList();
  }

  Future<T> findById(int id) async {
    final sql = '''SELECT * FROM $table
    WHERE id = ?''';

    final data = await db.rawQuery(sql, [id]);

    return model.fromJson(jsonData: data.first);
  }

  // Count all the items
  Future<int> count() async {
    final data = await db.rawQuery('''SELECT COUNT(*) FROM $table''');

    int count = data[0].values.elementAt(0);
    int idForNewItem = count++;
    return idForNewItem;
  }

  // clear the table
  Future<void> delete() async {
    // truncate current database table
    await db.rawQuery('''DELETE FROM $table''');
  }
}

2-正确调用超级构造函数

TimesheetRepository

class TimesheetRepository extends BaseRepository<TimesheetModel> {
  ///IMHO you should not pass TimesheetModel instance here, it is really redundant
  ///you can create a parse class that receives the type and a json and does the 
  ///trick
  TimesheetRepository() : super(table: 'timesheets', model: TimesheetModel());
}

3-将正确的返回值添加到您的fromJson方法中

abstract class BaseModel {
  BaseModel fromJson({Map<String, dynamic> jsonData});
}

我无法将其与数据库集成进行测试,因此请让我知道这是否起作用.

Dart相关问答推荐

根据 Id 比较两个不同的 List

将 Stream> 转换为 Stream

Dart 中的静态构造函数

Flutter | Dart:URI的目标不存在

错误:不要从另一个包中导入实现文件

如何使用文本小部件设置多行文本?

不要将 PageView 居中 - Flutter

Flutter:并非所有本地化代表都支持应用程序的语言环境

参数类型PointerEvent不能分配给参数类型PointerDownEvent

如何组织混合HTTP服务器+web客户端Dart元素文件?

不推荐使用AnteStorStateofType,请改用findAncestorStateOfType

如何在dart中的多个文件中编写多个单元测试?

Dart:实例变量在私有类中应该是私有的还是公共的?

Dart 中的抽象基类

可以在 Dart 中的抽象类中声明静态方法吗?

DART:future的语法 then

从dart语言列表中过滤空值的最佳方法是什么

如何在 Dart 中连接两个字符串?

如何从 Dart 中的列表中获取随机元素?

dart中的动态和对象有什么区别?