【问题标题】:How to refresh page(get data api event trigger again) when event delete triggered with flutter_bloc?使用flutter_bloc触发事件删除时如何刷新页面(再次获取数据api事件触发)?
【发布时间】:2021-11-15 00:07:29
【问题描述】:

我从 api 获取数据并将它们显示为列表,然后选择特定索引以从列表和数据库中删除数据。实际上,该特定项目正在从数据库中删除,但需要再次触发获取数据 api,然后列表将被更新。

抱歉,我忘了说我正在使用flutter_bloc。

代码片段:

List<AlertData> recordings;
class RecordingsScreen extends StatelessWidget {
  final void Function() onPop;
  const RecordingsScreen({Key key, this.onPop}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: MyTheme.white,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: MyTheme.primaryColor,
        automaticallyImplyLeading: false,
        title: Row(
          children: [
            IconButton(
                icon: Icon(
                  Icons.arrow_back_ios,
                  color: MyTheme.secondryColor,
                ),
                onPressed: onPop),
            Text(
              "RECORDINGS",
              style: TextStyle(
                color: MyTheme.secondryColor,
              ),
            ),
          ],
        ),
      ),
      body: BlocProvider(
        create: (context) => AlertBloc()..add(GetOldAlerts()),
        child: BlocBuilder<AlertBloc, AlertState>(
          builder: (BuildContext context, AlertState state) {
            if (state.alertStatus == AlertStatus.gettingOldAlertsFailed ||
                state.alertStatus == AlertStatus.deletionAlertFailed) {
              return _OldAlertFailed(
                error: state.res['message'],
              );
            }
            if (state.alertStatus == AlertStatus.gotOldAlerts ||
                state.alertStatus == AlertStatus.deletedAlert ||
                state.alertStatus == AlertStatus.deletionAlert) {

               recordings = [];
               recordings =
                  BlocProvider.of<AlertBloc>(context).oldAlertModel;
             
              return _bodyForm(state);
            }
            return Center(
              child: ProcessingIndicator(),
            );
          },
        ),
      ),
    );
  }
  _bodyForm(AlertState state ){
    return Stack(
      children: [
        _RecordingsForm(),
        state.alertStatus == AlertStatus.deletionAlert 
        ? _DeletionProcessBar()
        :Container()
      ],
    );
  }
}

从 api 获取的项目列表



class _RecordingsForm extends StatefulWidget {
  @override
  __RecordingsFormState createState() => __RecordingsFormState();
}

class __RecordingsFormState extends State<_RecordingsForm> {

  @override
  Widget build(BuildContext context) {
    return Container(
        child: ListView.builder(
            itemCount: recordinds.length,
            itemBuilder: (context, index) {
              return ListTile(
                  trailing: recordinds[index].isPlaying
                      ? Image.asset(
                          PLAYING_ASSET,
                          height: 20,
                          width: 20,
                        )
                      : PopupMenuButton(
                          elevation: 3,
                          child: Image.asset(
                            VERTICAL_MENU_ASSET,
                            height: 20,
                            width: 20,
                          ),
                          itemBuilder: (_) => <PopupMenuEntry<String>>[
                                new PopupMenuItem(
                                    value: "DELETE",
                                    height: 10,
                                    child: Row(
                                      children: [
                                        Text(
                                          "DELETE",
                                          style: TextStyle(
                                              fontSize: 13,
                                              fontWeight: FontWeight.bold),
                                        ),
                                        SizedBox(width: 4),
                                        Image.asset(
                                          DELETE_ASSET,
                                          height: 13,
                                          width: 13,
                                        ),
                                      ],
                                    ))
                              ],
                          onSelected: (val) => BlocProvider.of<AlertBloc>(context).add(DeleteAlert(
                                recordinds[index].alertId.toString()))), //HERE DELETE ITEM EVENT GOT TRIGGERED.
                  contentPadding: ...,
                     
                  leading: ...,
                  title: ...);
            }));
  }


}

这里是问题的short_video

【问题讨论】:

  • 如何使用 BloC 获取要在列表中显示的项目?您可以在删除项目后再次调用它以刷新列表。
  • 天啊,我怎么这么笨。是的,你是对的,if (state.alertStatus == AlertStatus.deletedAlert) { BlocProvider.of&lt;AlertBloc&gt;(context).add(GetOldAlerts()); }。这很简单。顺便说一句,非常感谢你意识到我的愚蠢。

标签: flutter dart state-management flutter-bloc


【解决方案1】:

正如之前在 cmets 中提到的,您可以通过调用最初填充 List 的 Bloc 方法在删除后简单地调用刷新 List。

列表未刷新的原因是您调用的 Bloc 提供程序只是简单地从列表中删除项目。您可以做的另一种方法是在删除期间更新 StreamController,以便 BlocProvider 将使用新/更新的列表再次重建。

这是一个示例,但我使用的是 StreamBuilder。可以对您的问题应用类似的方法。

class AlbumsBloc {
  final _repository = Repository();
  final _albumFetcher = StreamController<List<AlbumModel>>();

  /// bloc.allAlbums is set as stream on StreamBuilder
  /// i.e.
  /// StreamBuilder(
  ///   stream: bloc.allAlbums,
  ///   ...
  /// ),
  Stream<List<AlbumModel>> get allAlbums => _albumFetcher.stream;

  fetchAlbum() async {
    /// In this sample, Repository contains HTTP requests 
    /// to fetch List<AlbumModel>
    List<AlbumModel> listAlbums = await _repository.fetchAllAlbums();
    /// Add the List on Stream
    _albumFetcher.sink.add(listAlbums);
  }

  deleteAlbumItem(String albumItem){
    /// HTTP request to delete album item
    await _repository.deleteAlbumItem(id: albumItem);
    /// Fetch albums again
    List<AlbumModel> listAlbums = await _repository.fetchAllAlbums();
    /// Update the Stream
    _albumFetcher.sink.add(listAlbums);
  }

  dispose() {
    _albumFetcher.close();
  }
}

final bloc = AlbumsBloc();

【讨论】:

  • 您能解释一下我将如何将 StreamController 与 flutter_bloc 一起使用吗?实际上我曾经使用过实时数据更改但无法处理它所以将其删除。
  • 我可以提供一个使用 StreamBuilder 的示例,但类似的方法可以应用于您的问题。
猜你喜欢
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 2010-10-17
  • 2022-01-01
  • 1970-01-01
  • 2014-05-30
相关资源
最近更新 更多