如何使用 MultiBlocProvider 并在子部件中传递多个提供者?

How to use MultiBlocProvider and pass multiple provider in a child widget?

我仍在学习如何使用 bloc。目前我有两个集团,PostBloc 和 LocationBloc。 PostBloc 只会调用 api 到 post 并有自己的演示文稿 ui。 LocationBloc 只会获取位置,并且可以在任何功能中全局使用。我想在 post 将其发送到服务器之前包含该位置。但我不知道如何使用这两个集团。下面的代码是我正在尝试做的一个例子。我不知道这是不是正确的做法。

class PostPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider(create: (_) => sl<PostBloc>()),
        BlocProvider(create: (_) => sl<LocationBloc>()),
      ],
      child: Scaffold(
        body: buildBody(),
      ),
    );
  }

  buildBody() {
    return BlocListener<PostBloc, PostState>(
      listener: (context, state) {
        if (state is Empty) {
        } else if (state is Loading) {
        } else if (state is Loaded) {
          //show snackbar
        } else if (state is Error) {}
      },
      child: InitialDisplay(),
    );
  }
}

class InitialDisplay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          RaisedButton(onPressed: () {
            showDialog(
                barrierDismissible: false,
                context: context,
                builder: (_) {
                  return BlocProvider<PostBloc>.value(
                  value: BlocProvider.of<PostBloc>(context),
                  child: BlocProvider<LocationBloc>.value(
                      value: BlocProvider.of<LocationBloc>(
                          context),
                      child: PostDetails()));
                });
          }),
        ],
      ),
    );
  }
}

class PostDetails extends StatefulWidget {
  const PostDetails({Key key}) : super(key: key);
  @override
  _PostDetailsState createState() => _PostDetailsState();
}

class _PostDetailsState extends State<PostDetails> {
  double latitude;
  double longitude;

  @override
  Widget build(BuildContext context) {
    return BlocListener<LocationBloc, LocationBlocState>(
      listener: (context, state) {
        if (state is LocationBlocLoadedEvent) {
          latitude = state.location.latitude;
          longitude = state.location.longitude;
        }
      },
      child: Dialog(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
          backgroundColor: Colors.transparent,
          child: _buildWidget(context)),
    );
  }

  _buildWidget(BuildContext context) {
    return Container(
        height: MediaQuery.of(context).size.height * .55,
        decoration: BoxDecoration(
            color: Colors.white,
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(16)),
        child: RaisedButton(onPressed: () {
          postWithLocation();
        }));
  }

  void postWithLocation() {
    BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
    BlocProvider.of<PostBloc>(context).add(PostEvent(
      post: 'Test post with location',
      long: longitude,
      lat: latitude,
    ));
  }
}

编辑: 这是我得到的错误。我认为这是因为我只通过了 PostBloc,因为我不知道如何通过多个 bloc,或者这是否是正确的做法。

Error: Could not find the correct Provider<LocationBloc> above this BlocListener<LocationBloc, LocationBlocState> Widget

编辑 2: BlocLocation 现在正在工作。我刚刚传递了与 PostBloc 相同的 blocLocation 值。我现在的问题是 PostBloc 在 postWithLocation() 函数

中提交之前没有等待 LocationBloc 获取位置
BlocProvider<PostBloc>.value(
  value: BlocProvider.of<PostBloc>(context),
  child: BlocProvider<LocationBloc>.value(
      value: BlocProvider.of<LocationBloc>(
          context),
      child: PostDetails()));

这是在 Bloc 中执行排序作业的正确方法。

// _PostDetailsState
  @override
  Widget build(BuildContext context) {
    return BlocListener<LocationBloc, LocationBlocState>(
      listener: (context, state) {
        if (state is LocationBlocLoadedEvent) {
          final latitude = state.location.latitude;
          final longitude = state.location.longitude;
          BlocProvider.of<PostBloc>(context).add(PostEvent(
            post: 'Test post with location',
            long: longitude,
            lat: latitude,
          ));
        }
      },
      child: Dialog(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
          backgroundColor: Colors.transparent,
          child: _buildWidget(context)),
    );
  }

同时删除 postWithLocation 中的一些代码。

  void postWithLocation(context) {
    BlocProvider.of<LocationBloc>(context).add(LoadLocationEvent());
  }