4

我正在努力将块模式放入我的 Flutter 应用程序中。我正在使用这个库让它对我来说更简单一点:https ://felangel.github.io/bloc/#/

我有一个主要问题。我怎样才能让我的 Bloc 可以在全球范围内访问,而不会一次又一次地传递下去?

这是我的代码:

主要飞镖:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'db_bloc.dart';
import 'NotesPage.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  final DatabaseBloc _dbNoteBloc = DatabaseBloc();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: BlocProvider<DatabaseBloc>(
        bloc: _dbNoteBloc,
        child: NotesPage(),
      ),
    );
  }

  @override
  void dispose() {
    _dbNoteBloc.dispose();
    super.dispose();
  }
}

备注页:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import 'db_bloc.dart';
import 'note_model.dart';

class NotesPage extends StatefulWidget {
  _NotesPageState createState() => _NotesPageState();
}

class _NotesPageState extends State<NotesPage> {
  @override
  Widget build(BuildContext context) {
    final DatabaseBloc _dbNoteBloc = BlocProvider.of<DatabaseBloc>(context);

    return BlocBuilder<NoteDbEvent, List<Note>>(
      bloc: _dbNoteBloc,
      builder: (BuildContext context, List<Note> state) {
        return Scaffold(
          appBar: AppBar(
            title: Text("bla"),
            actions: <Widget>[
              // action button
              IconButton(
                icon: Icon(Icons.refresh),
                onPressed: () => _dbNoteBloc
                    .dispatch(NoteDbEvent(type: NoteDbEventType.GetAll)),
              ), // action button
            ],
          ),
          body: ListView.builder(
            itemCount: state.length,
            itemBuilder: (BuildContext context, int index) {
              return Column(
                children: <Widget>[
                  ListTile(
                    title: Text('${state[index].title}'),
                    onLongPress: () => showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text("Löschen"),
                              content: Text(
                                  "Möchtest du diese Notiz wirklich löschen?"),
                              actions: <Widget>[
                                FlatButton(
                                  child: Text("Close"),
                                  onPressed: () {
                                    Navigator.of(context).pop();
                                  },
                                ),
                                FlatButton(
                                  child: Text("Delete"),
                                  onPressed: () {
                                    _dbNoteBloc.dispatch(NoteDbEvent(
                                        value: state[index],
                                        type: NoteDbEventType.Delete));
                                    Navigator.of(context).pop();
                                  },
                                ),
                              ],
                            );
                          },
                        ),
                  ),
                  Divider(
                    height: 0,
                  ),
                ],
              );
            },
          ),
        );
      },
    );
  }
}

正如您所看到的,我在小部件代码中也有显示对话框代码,我很想将其导出,但到目前为止,如果显示对话框代码不在 Bloc 生成器中,则它无法访问 _dbNoteBloc。

谢谢你的每一个帮助。

PS:如果有人需要这里的 Bloc 代码,它是:

import 'package:bloc/bloc.dart';
import "note_model.dart";
import 'db.dart';

enum NoteDbEventType { Insert, Delete, Update, GetAll }

class NoteDbEvent {
  NoteDbEventType type;
  Note value;
  NoteDbEvent({this.type, this.value});
}

class DatabaseBloc extends Bloc<NoteDbEvent, List<Note>> {
  final db = DBProvider();

  @override
  List<Note> get initialState =>  [];

  @override
  Stream<List<Note>> mapEventToState(List<Note> currentState, NoteDbEvent event) async* {
    switch (event.type) {
      case NoteDbEventType.Delete:
        db.deleteNote(event.value.id);
        currentState.removeWhere((item) => item.id == event.value.id);
        yield List.from(currentState);
        break;
      case NoteDbEventType.Insert:
        int id = await db.newNote(event.value);
        event.value.id = id;
        currentState.add(event.value);
        yield List.from(currentState);
        break;
      case NoteDbEventType.Update:
        yield currentState;
        break;
      case NoteDbEventType.GetAll:
        var list = await db.getAllNotes();
        yield currentState = list;
        break;
    }
  }
}
4

1 回答 1

2

BLoC 模式更好地用于管理单个特定小部件的状态,例如屏幕。

BLoC 模式不是由单个特定小部件使用,而是用于每个 UI 功能。这意味着您的小部件与您的 BLoC 几乎没有关联。您始终可以选择是否为 UI 的每个部分使用它。显然,将 BLoC 拆分为多个 BLoC 是您的工作。

对于不知道的人:如果您想使用 BLoC 模式让您的生活更轻松,您可以使用这里flutter_bloc的包,它可以让您访问许多助手。

如果你需要关于包的帮助,你也可以来gitter

关于显示对话框,您也许可以使用BlocListener相当新的。

于 2019-06-23T08:19:19.227 回答