【问题标题】:Bloc pattern not getting notes without passing through DatabaseBloc 模式在不通过数据库的情况下没有得到笔记
【发布时间】:2020-03-17 14:54:19
【问题描述】:

我有一个 工作 颤振应用程序,它与 blocSQflite 一起工作,以便从数据库中获取一些笔记并将它们显示在简单的视图列表。为了更好地理解 bloc 模式,我想“消除”数据库部分,并将从数据库中获取的笔记替换为我编写的硬编码笔记列表。 (我认为唯一有意义的文件是 note_bloc.dart 但以防万一我会发布剩余的代码) 所以实现 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 的 statefull 小部件代码:

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(),
                                );

【问题讨论】:

    标签: asynchronous flutter dart async-await bloc


    【解决方案1】:

    您在哪里调用小部件上的 bloc getNotes() 函数。

    也许您是在进入小部件之前在流中添加信息,所以当您构建小部件时,您的流没有任何价值。

    您可以尝试的一件事是使用 BehaviorSubject 而不是 Stream。 BehaviorSubject 总是发送最后一个下沉的值,所以如果我的假设是正确的,它应该可以工作。

    【讨论】:

    • 谢谢!问题正是你提到的那个。使用异步等待功能,小部件首先通过 initState,然后构建第一个“空白”上下文,然后(当它通过流接收注释时)最终再次渲染小部件并显示注释。如果没有 async 函数,它会在初始化 bloc (_notesBloc) 后立即在 initState 函数中获取注释,因此当真正的上下文渲染发生时,不会收到并确实显示注释。
    猜你喜欢
    • 2012-02-08
    • 1970-01-01
    • 2018-01-07
    • 2015-02-12
    • 1970-01-01
    • 2018-09-17
    • 2011-07-07
    • 2011-08-31
    • 2020-12-27
    相关资源
    最近更新 更多