Bloc 模式不通过数据库就得不到笔记
Bloc pattern not getting notes without passing through Database
我有一个 working flutter 应用程序,可以与 bloc 和 SQflite 一起使用,以便从数据库中获取一些笔记并将它们显示在一个简单的 ViewList 中。为了更好地理解 bloc patter,我想 "eliminate" 数据库部分并将从数据库中获取的注释替换为我编写的硬编码注释列表。
(我认为唯一有意义的文件是 note_bloc.dart 但以防万一我将 post 剩余的代码)
所以实现 note_bloc 模式并完美运行的代码是这样的:
class NotesBloc implements BlocBase {
final _notesController = StreamController<List<Note>>.broadcast();
StreamSink<List<Note>> get _inNotes => _notesController.sink;
Stream<List<Note>> get notes => _notesController.stream;
NotesBloc() {
getNotes();
}
@override
void dispose() {
_notesController.close();
}
Future<void> getNotes() async {
List<Note> notesFromDB = await DBProvider.db.getNotes();
_inNotes.add(notesFromDB);
}
函数DBProvider.db.getNotes()是这样写的(才知道):
getNotes() async {
final db = await database;
var res = await db.query('note');
List<Note> notes = res.isNotEmpty ? res.map((note) => Note.fromJson(note)).toList() : [];
return notes;
}
我尝试做的第一件事是像这样更改 notes_bloc 的 getNotes 函数:
void getNotes() async {
// List<Note> notesFromDB = await DBProvider.db.getNotes();
List<Note> noteHardcoded = [new Note()];
_inNotes.add(noteHardcoded);
}
简单易行,但如果我启动该应用程序,它不会出错,并且会陷入无限循环,无法显示任何注释...
如果相反,我只是从这样的异步函数中获取硬编码注释:
void getNotes() async {
// List<Note> notesFromDB = await DBProvider.db.getNotes();
List<Note> noteHardcoded = await asyncNotes();
_inNotes.add(noteHardcoded);
}
asyncNotes() async {
List<Note> noteHardcoded = [new Note()];
return noteHardcoded;
}
如预期的那样没有问题!!
这就像 notes_bloc 的 getNotes() 只能从 ASYNC 函数中获取注释,我不知道为什么..
这是我使用 notes_bloc:
的有状态小部件代码
class _NotesPageState extends State<NotesPage> {
NotesBloc _notesBloc;
@override
void initState() {
super.initState();
print("I'm in the initState going to assign _notesBlock");
_notesBloc = BlocProvider.of<NotesBloc>(context);
print("I'm in the initState and i assigned _notesBlock");
}
StreamBuilder<List<Note>>(
stream: _notesBloc.notes,
builder: (BuildContext context, AsyncSnapshot<List<Note>> snapshot) {
print("building context..");
// Make sure data exists and is actually loaded
if (snapshot.hasData) {
// If there are no notes (data), display this message.
if (snapshot.data.length == 0) {
return Text('No notes');
}
List<Note> notes = snapshot.data;
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Note note = notes[index];
return GestureDetector(
onTap: () {
_navigateToNote(note);
},
child: Container(
height: 40,
child: Text(
'Note ' + note.id.toString(),
style: TextStyle(
fontSize: 18
),
),
),
);
},
);
}
return Center(
child: CircularProgressIndicator(),
);
您在哪里调用小部件上的 bloc getNotes() 函数。
也许您在进入小部件之前将信息添加到流中,因此当您构建小部件时,流中没有任何价值。
您可以尝试的一件事是使用 BehaviorSubject 而不是 Stream。 BehaviorSubject 总是发送最后一个下沉值,所以如果我的假设是正确的,它应该可以工作。
我有一个 working flutter 应用程序,可以与 bloc 和 SQflite 一起使用,以便从数据库中获取一些笔记并将它们显示在一个简单的 ViewList 中。为了更好地理解 bloc patter,我想 "eliminate" 数据库部分并将从数据库中获取的注释替换为我编写的硬编码注释列表。 (我认为唯一有意义的文件是 note_bloc.dart 但以防万一我将 post 剩余的代码) 所以实现 note_bloc 模式并完美运行的代码是这样的:
class NotesBloc implements BlocBase {
final _notesController = StreamController<List<Note>>.broadcast();
StreamSink<List<Note>> get _inNotes => _notesController.sink;
Stream<List<Note>> get notes => _notesController.stream;
NotesBloc() {
getNotes();
}
@override
void dispose() {
_notesController.close();
}
Future<void> getNotes() async {
List<Note> notesFromDB = await DBProvider.db.getNotes();
_inNotes.add(notesFromDB);
}
函数DBProvider.db.getNotes()是这样写的(才知道):
getNotes() async {
final db = await database;
var res = await db.query('note');
List<Note> notes = res.isNotEmpty ? res.map((note) => Note.fromJson(note)).toList() : [];
return notes;
}
我尝试做的第一件事是像这样更改 notes_bloc 的 getNotes 函数:
void getNotes() async {
// List<Note> notesFromDB = await DBProvider.db.getNotes();
List<Note> noteHardcoded = [new Note()];
_inNotes.add(noteHardcoded);
}
简单易行,但如果我启动该应用程序,它不会出错,并且会陷入无限循环,无法显示任何注释...
如果相反,我只是从这样的异步函数中获取硬编码注释:
void getNotes() async {
// List<Note> notesFromDB = await DBProvider.db.getNotes();
List<Note> noteHardcoded = await asyncNotes();
_inNotes.add(noteHardcoded);
}
asyncNotes() async {
List<Note> noteHardcoded = [new Note()];
return noteHardcoded;
}
如预期的那样没有问题!! 这就像 notes_bloc 的 getNotes() 只能从 ASYNC 函数中获取注释,我不知道为什么..
这是我使用 notes_bloc:
的有状态小部件代码class _NotesPageState extends State<NotesPage> {
NotesBloc _notesBloc;
@override
void initState() {
super.initState();
print("I'm in the initState going to assign _notesBlock");
_notesBloc = BlocProvider.of<NotesBloc>(context);
print("I'm in the initState and i assigned _notesBlock");
}
StreamBuilder<List<Note>>(
stream: _notesBloc.notes,
builder: (BuildContext context, AsyncSnapshot<List<Note>> snapshot) {
print("building context..");
// Make sure data exists and is actually loaded
if (snapshot.hasData) {
// If there are no notes (data), display this message.
if (snapshot.data.length == 0) {
return Text('No notes');
}
List<Note> notes = snapshot.data;
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) {
Note note = notes[index];
return GestureDetector(
onTap: () {
_navigateToNote(note);
},
child: Container(
height: 40,
child: Text(
'Note ' + note.id.toString(),
style: TextStyle(
fontSize: 18
),
),
),
);
},
);
}
return Center(
child: CircularProgressIndicator(),
);
您在哪里调用小部件上的 bloc getNotes() 函数。
也许您在进入小部件之前将信息添加到流中,因此当您构建小部件时,流中没有任何价值。
您可以尝试的一件事是使用 BehaviorSubject 而不是 Stream。 BehaviorSubject 总是发送最后一个下沉值,所以如果我的假设是正确的,它应该可以工作。