也许其他人有和我一样的问题,所以这里是我如何实现它,最后。我正在为ObjectBox展示这个,但有些方法也适用于Hive或其他数据库。
我的问题是关于建立ObjectBox流,特别是关于将ObjectBox数据模型转换为流中的我的域实体。
来自数据层中的ObjectBox的数据流,它还包含存储库实现,通过域层中的契约(我在这里跳过用例)到表示层,在这里我使用颤振块管理状态。
todo域实体(仅显示id以缩短内容):
class Todo extends Equatable{
Todo(this.id);
final String id;
@override
List<Object?> get props => [id,];
}
ObjectBox的数据模型,包括与域实体之间的转换方法
@Entity()
class TodoObjectBox {
@Id()
int id;
final String todoId;
TodoObjectBox ({
this.id = 0,
required this.todoId});
factory TodoObjectBox.toObjectbox(Todo todo, int obId) => TodoObjectBox(
id: obId,
todoId: todo.id,
);
User fromObjectbox() => Todo(
id: todoId,
);
}
方法toObjectBox
需要内部的整数Objectbox id,我在存储todo时将其补充到方法中。
现在,在本地数据源实现中,我有以下类来流式处理待办事项。
@override
Stream<List<Todo>> streamTodos() {
Stream<List<TodoObjectBox>> todoObStream = objectbox.Todo.query()
.watch(triggerImmediately: true).map((query) => query.find());
StreamTransformer<List<TodoObjectBox>, List<Todo>> streamTransformer =
StreamTransformer<List<TodoObjectBox>, List<Todo>>.fromHandlers(
handleData: (List<TodoObjectBox> data, EventSink sink) {
var todos = data!.map((todoOb) {
final Todo todo = todoOb.fromObjectbox();
return todo;
}).toList();
sink.add(todos);
},
handleError: (Object error, StackTrace stacktrace, EventSink sink) {
sink.addError('Something went wrong: $error');
},
handleDone: (EventSink sink) => sink.close(),
);
return streamTransformer.bind(todoObStream);
}
生成流,然后从数据模型TodoObjectBox
转换为域实体Todo
。
在表示层中,我用存储库和事件TodoListRequested
实例化了一个TodoListBloc
以启动流。然后,block使用以下例程处理此事件:
Future<void> _onListRequested(
TodoListRequested event,
Emitter<TodoListState> emit,
) async {
emit(state.copyWith(status: () => DataTransStatus.loading));
await emit.forEach<dynamic>(
_todoRepository.streamTodos(),
onData: (todos) {
return state.copyWith(
status: () => DataTransStatus.success,
todosList: () => List.from(
todos.map((t) => TodosListViewmodel.fromDomain(t);
)),
);
},
onError: (Object error, StackTrace stack) {
print('Bloc stream error $error $stack');
return state.copyWith(
status: () => DataTransStatus.failure,
);
},
);
}
我希望这能帮助那些试图使用不同的数据模型/实体从Objectbox或其他数据库流到表示层的人。
这个答案的一些背景可以在ResoCoder的TDD教程和BlocLibrary的Todo教程中找到。