Szhangbiao's blog

记录一些让自己可以回忆的东西

0%

Hive在Flutter Web中使用Stream

受到在做 Android 开发时 MVVM 架构的影响,在开发 Flutter 项目时,在架构实际上我都会有意的向 MVVM 方向上靠。所幸 dart 语言的语法有点像 Java 和 Kotlin 的结合体,所以架构上除了 View 层,其它层都非常的相似。

需求

有个带搜索框的列表页面,数据从本地数据库中加载而来,列表页面中还有个Add按钮,点击按钮后跳转到一个新页面,新页面可以添加新的数据。当新数据添加完成后返回到列表页面,列表页面需要把符合条件的新数据加载出来。
思路:

  • 数据库的框架有接口对当前数据添加一个观察者,当有数据变动时就触发之前的加载逻辑。
  • Hive 框架中的 Box 有个watch()方法,它返回一个 Stream 类型的数据,用于监听单个数据或者所有数据的变动(取决于是否传递单个数据的 key)。

解决方案

跟 floor 框架 Dao 里声明的 Stream 的方法一样,当数据发生变化时,会自动更新。
Hive 版的解决方案如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import 'package:hive/hive.dart';

@override
Stream<List<Note>> getAllNotes(String userId) {
return Stream.fromFuture(_getCachedBox()).flatMap((innerBox) => _watchNotes(innerBox));
}

@override
Stream<List<Note>> searchNotes(String userId, String searchKey) {
return Stream.fromFuture(_getCachedBox()).flatMap((innerBox) => _watchNotes(innerBox, filter: searchKey));
}

Stream<List<Note>> _watchNotes(Box<Note> noteBox, {String filter = ''}) {
return noteBox.watch().map((event) => _getAllStoreNotes(noteBox, filter)).startWith(_getAllStoreNotes(noteBox, filter));
}

List<Note> _getAllStoreNotes(Box<Note> noteBox, String filter) {
List<Note> noteList = noteBox.values.where((note) => filter == '' || note.title?.contains(filter) == true).toList();
// 对note按照title排序
noteList.sort((a, b) {
return a.title?.compareTo(b.title ?? '') ?? 0;
});
return noteList;
}

这样列表页面的数据重新加载就取决于当前数据是否真的有变动。