簡體   English   中英

如何使一個集團全球可訪問

[英]How to make a bloc global accessible

我正在努力將塊模式放入我的 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();
  }
}

備注頁:

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

BLoC 模式更適合用於管理單個特定小部件(例如屏幕)的狀態。

BLoC 模式不是由單個特定小部件使用,而是用於每個 UI 功能。 這意味着您的小部件並非很難與您的 BLoC 相關聯。 對於 UI 的每個部分,您始終可以選擇是否使用它。 顯然,將 BLoC 拆分為多個 BLoC 是您的工作。

對於不知道的人:如果你想使用 BLoC 模式讓你的生活更輕松,你可以使用flutter_bloc在這里,它可以讓你訪問許多幫助程序。

如果你需要關於包的幫助,你也可以來gitter

關於顯示對話框,您可以使用相當新的BlocListener

這是8.0版本的,現在頁面有這個主題的文章: https://bloclibrary.dev/#/recipesflutterblocaccess?id=global-access

基本上,您需要制作材料應用程序的 BlocProvider Parent,這里顯示的是鏈接中的內容(如果現在已經死了):

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

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

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (BuildContext context) => CounterBloc(),
      child: MaterialApp(
        title: 'Flutter Demo',
        home: CounterPage(),
      ),
    );
  }

頁面中的關鍵文本是:

將整個 MaterialApp 包裝在 BlocProvider 中是使 CounterBloc 實例全局可訪問的關鍵。 現在我們可以使用 BlocProvider.of(context); 從應用程序中我們有 BuildContext 的任何地方訪問我們的 CounterBloc;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM