gpt4 book ai didi

flutter - 在 BLoC 中触发初始事件

转载 作者:行者123 更新时间:2023-12-03 02:43:50 24 4
gpt4 key购买 nike

示例状态:

abstract class ExampleState extends Equatable {
const ExampleState();
}

class LoadingState extends ExampleState {
//
}

class LoadedState extends ExampleState {
//
}

class FailedState extends ExampleState {
//
}
示例_事件:
abstract class ExampleEvent extends Equatable {
//
}

class SubscribeEvent extends ExampleEvent {
//
}

class UnsubscribeEvent extends ExampleEvent {
//
}

class FetchEvent extends ExampleEvent {
//
}
示例_块:
class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {
@override
ExampleState get initialState => LoadingState();

@override
Stream<ExampleState> mapEventToState(
ExampleEvent event,
) async* {
if (event is SubscribeEvent) {
//
} else if (event is UnsubscribeEvent) {
//
} else if (event is FetchEvent) {
yield LoadingState();
try {
// network calls
yield LoadedState();
} catch (_) {
yield FailedState();
}
}
}
}
示例_屏幕:
class ExampleScreenState extends StatelessWidget {
// ignore: close_sinks
final blocA = ExampleBloc();

@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocBuilder<ExampleBloc, ExampleState>(
bloc: blocA,
// ignore: missing_return
builder: (BuildContext context, state) {
if (state is LoadingState) {
blocA.add(Fetch());
return CircularProgressBar();
}

if (state is LoadedState) {
//...
}

if (state is FailedState) {
//...
}
},
),
);
}
}
正如您在 example_bloc 中看到的,初始状态是 LoadingState() 并且在构建中它显示圆形进度条。我使用 Fetch() 事件来触发下一个状态。但我在那里使用它感觉不舒服。我想做的是:
当应用程序启动时,它应该显示 LoadingState 并开始网络调用,然后当它全部完成时,它应该显示 LoadedState 和网络调用结果,如果出现问题,它应该显示 FailedState。我想在不做的情况下实现这些
if (state is LoadingState) {
blocA.add(Fetch());
return CircularProgressBar();
}

最佳答案

您的不适确实是有原因的 - 不应从 build() 触发任何事件方法(build() 可以根据 Flutter 框架需要多次触发)
我们的情况是在创建 Bloc 时触发初始事件
可能性概述

  • 使用 BlocProvider 插入 Bloc 的情况 - 这是首选方式
  • create:回调仅在 BlocProvider 挂载时触发一次,而 BlocProvider 在卸载 BlocProvider 时将 close() bloc
        class ExampleScreenState extends StatelessWidget {

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    body: BlocProvider(
    create: (context) => ExampleBloc()..add(Fetch()), // <-- first event,
    child: BlocBuilder<ExampleBloc, ExampleState>(
    builder: (BuildContext context, state) {
    ...
    },
    ),
    ),
    );
    }
    }
  • State 中创建 Bloc 的情况Statefull 小部件
  • class _ExampleScreenStateState extends State<ExampleScreenState> {
    ExampleBloc _exampleBloc;

    @override
    void initState() {
    super.initState();
    _exampleBloc = ExampleBloc();
    _exampleBloc.add(Fetch());
    // or use cascade notation
    // _exampleBloc = ExampleBloc()..add(Fetch());
    }

    @override
    void dispose() {
    super.dispose();
    _exampleBloc.close(); // do not forget to close, prefer use BlocProvider - it would handle it for you
    }

    @override
    Widget build(BuildContext context) {
    return Scaffold(
    body: BlocBuilder<ExampleBloc, ExampleState>(
    bloc: _exampleBloc,
    builder: (BuildContext context, state) {
    ...
    },
    ),
    );
    }
    }
  • 在 Bloc 实例创建时添加第一个事件 - 这种方式在测试时有缺点,因为第一个事件是隐式的
  • class ExampleBloc extends Bloc<ExampleEvent, ExampleState> {

    ...

    ExampleBloc() {
    add(Fetch());
    }
    }

    // insert it to widget tree with BlocProvider or create in State
    BlocProvider( create: (_) => ExampleBloc(), ...

    // or in State

    class _ExampleScreenStateState extends State<ExampleScreenState> {
    final _exampleBloc = ExampleBloc();
    ...
    PS请随时在评论中联系我

    关于flutter - 在 BLoC 中触发初始事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62648103/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com