【问题标题】:How To Listen to BLoC Events From Another Screen in Flutter如何在 Flutter 中从另一个屏幕监听 BLoC 事件
【发布时间】:2023-03-24 16:20:01
【问题描述】:

已解决:我得到了另一个状态,而不是我预期的状态

我的应用中有两个屏幕。第一个包含产品,每个产品都用CheckboxListTile包装,复选框值是一个变量,它的值是通过检查产品的ID是否存在于名为selectedItemsList的列表中来指定的,现在第二个屏幕是购物车包含从第一个屏幕中选择的产品的屏幕,每个 cartItem 都包含在 Dismissible 中,onDismissed 函数从购物车中删除产品,并从 selectedItemsList 列表中删除它的 id。

当我按下后退按钮并从购物车屏幕导航回产品屏幕时,我想要更改从购物车中删除的复选框值。

我的目标更明确:

  1. 产品屏幕有 2 个产品(p1 和 p2)。
  2. 我选择 p1,它被添加到购物车,它的 id 被添加到 selectedItemsList
  3. p1 复选框的值为真(选中)。
  4. 我导航到购物车屏幕并从那里删除 p1。
  5. p1 现已从购物车中删除,其 id 已从 selectedItemsList 中删除。
  6. 我按下返回按钮并导航回产品屏幕。
  7. p1 复选框的值应该为 false(未选中),因为它的 id 不在 selectedItemsList 中,但它仍然是 true(选中)。
  8. 当我从购物车屏幕中的购物车中删除产品时,我想更新(或实际重建)产品屏幕。

我正在使用bloc 模式实现上述内容。我正在从CartBloc 触发一个名为RemoveItemFromCart 的事件:

void _onDismissed({
    required BuildContext context,
    required int index,
  }) {
    BlocProvider.of<CartBloc>(context).add(
      RemoveItemFromCart(
        items: _cartItems,
        index: index,
        counts: _counts,
        filteredCounts: _filteredCounts,
        originalIndices: _originalIndices,
        filteredItems: _filteredCartItems,
        filtering: _filtering,
      ),
    );

    _firstTime = true;
  }

然后产生一个名为ItemRemovedFromCart 的状态:

if (event is RemoveItemFromCart) {
      if (event.filtering &&
          event.originalIndices.isNotEmpty &&
          event.filteredCounts.isNotEmpty &&
          event.filteredItems.isNotEmpty) {
        int itemIndex = event.items.indexWhere(
          (item) => item.id == event.filteredItems[event.index].id,
        );
        productsRepository.unSelectProduct(
          id: event.items[itemIndex].id,
        );
        event.items.removeAt(itemIndex);
        event.counts.removeAt(itemIndex);
        event.filteredItems.removeAt(event.index);
        event.filteredCounts.removeAt(event.index);
        event.originalIndices.removeAt(event.index);
      } else {
        productsRepository.unSelectProduct(
          id: event.items[event.index].id,
        );
        event.items.removeAt(event.index);
        event.counts.removeAt(event.index);
      }

      yield ItemRemovedFromCart(
        items: event.items,
        counts: event.counts,
        filteredCounts: event.filteredCounts,
        filteredItems: event.filteredItems,
        originalIndices: event.originalIndices,
      );
    }

在产品屏幕中,我正在使用BlocBuilder 在产生此状态时进行重建(但现在我只是尝试打印一个测试字符串以查看它是否正常工作):

BlocBuilder<CartBloc, CartState>(
  builder: (context, state) {
   if (state is ItemRemovedFromCart) print('asd');
   return _buildProductsList(products, context);
  },
)

打印语句没有被执行,如何监听另一个屏幕的事件?

提前致谢。

【问题讨论】:

  • 那么的状态是什么,如果它不是你所期望的呢?
  • 不,这是我所期望的,问题是当此状态由购物车屏幕触发的事件产生时,我想更新产品屏幕。 @nvoigt
  • 一切正常,我只想在 ItemRemovedFromCart 状态产生时更新产品屏幕。 @nvoigt
  • 但是两个屏幕都听同一个 BLoC,对吧?我会再问一次......因为你没有得到你期望的状态(打印 asd),你会得到什么状态
  • 而且...这可能是正确的吗?这是 BLoC 的最后一个状态吗?这种状态是怎么来的,你能调试你的 BLoC 吗?

标签: flutter dart bloc


【解决方案1】:

我发现 bloc 实例只要它们没有关闭或释放就一直在监听事件,所以如果我们想对来自另一个屏幕的事件采取行动,我们只需将一个事件添加到所需的 bloc 就可以了

【讨论】:

    猜你喜欢
    • 2019-01-05
    • 2022-01-25
    • 2020-03-26
    • 2020-02-18
    • 2022-12-15
    • 2020-04-29
    • 2020-11-22
    • 1970-01-01
    • 2023-03-29
    相关资源
    最近更新 更多