如何使集团全球可访问

时间:2019-02-04 17:30:54

标签: flutter bloc

我正在努力在自己的Flutter应用中放入集团模式。我正在使用这个库来简化它:https://felangel.github.io/bloc/#/

我有一个主要问题。我如何才能使我的Bloc在全球范围内都可以访问,而又不必一次又一次地传递下去。

这是我的代码:

main.dart:

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

NotesPage:

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,
                  ),
                ],
              );
            },
          ),
        );
      },
    );
  }
}

如您所见,我也将show Dialog Code包含在小部件代码中,我很想将其来源,但是直到现在,如果它不在Bloc Builder中,则show Dialog Code无法访问_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;
    }
  }
}

2 个答案:

答案 0 :(得分:0)

有评论建议使用Redux来管理全局状态。尽管Redux是一个不错的概念,但它相当复杂,并且还引入了很多样板。

使用小部件树上方的块提供程序的概念要容易得多。然后,您可以使用.of-syntax访问它。这在博客文章中显示:https://www.didierboelens.com/2018/08/reactive-programming---streams---bloc/

答案 1 :(得分:0)

  

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

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

对于不了解它的人:如果您想使用BLoC模式简化生活,可以使用flutter_bloc软件包here,该软件包可让您访问许多帮助程序。

如果您需要有关该软件包的帮助,也可以访问gitter

关于显示对话框,您可以使用全新的BlocListener