如何使用块过滤列表?

Bob*_*oby 5 flutter

所以,这是 bloc (参考https://bloclibrary.dev/#/flutterinfinitelisttutorial

class ProductBloc extends Bloc<ProductsEvent, ProductsState> {
  String categoryId, userId;
  int limit, offset, type;
  http.Client client;

  ProductBloc(
      {@required this.client,
      @required this.categoryId,
      @required this.userId,
      @required this.limit,
      @required this.offset,
      @required this.type});

  @override
  ProductsState get initialState => InitialProductsState();

  @override
  Stream<ProductsState> mapEventToState(ProductsEvent event) async* {
    final currentState = state;
    print(event);
    print(state);
    if (event is FetchProductsEvent && !_hasReachedMax(currentState)) {
      String categoryId = event.categoryId;
      try {
        if (currentState is InitialProductsState) {
          final posts = await _fetchProducts(categoryId, 0, 3);
          yield ProductsLoaded(product: posts, hasReachedMax: false);
          return;
        }

        if (currentState is ProductsLoaded) {
          final posts =
              await _fetchProducts(categoryId, currentState.product.length, 6);
          yield posts.isEmpty
              ? currentState.copyWith(hasReachedMax: true)
              : ProductsLoaded(
                  product: currentState.product + posts,
                  hasReachedMax: false,
                );
        }
      } catch (e) {
        print(e.toString());
        yield ProductsError();
      }
    } 
  }

  bool _hasReachedMax(ProductsState state) =>
      state is ProductsLoaded && state.hasReachedMax;

  Future<List<Products>> _fetchProducts(
      String categoryId, int startIndex, int limit) async {
    final response = await http.Client().post(Configuration.url +
        'api/getProductsTest/$categoryId/$startIndex/$limit');
    if (response.statusCode == 200) {
      List<dynamic> responseData = jsonDecode(response.body);
      final List<Products> products = [];
      responseData.forEach((singleProduct) {
        products.add(Products(
            productId: singleProduct['productId'],
            productName: singleProduct['productName'],
            isNew: singleProduct['isNew'],
            isHot: singleProduct['isHot'],
            productImage: singleProduct['productImage'],
            categoryId: singleProduct['categoryId'],
            productPrice: singleProduct['productPrice'],
            productDescription: singleProduct['productDescription'],
            isLiked: singleProduct['isLiked'],
            productColorId: singleProduct['productColorId'],
            image1: singleProduct['image1'],
            image2: singleProduct['image2'],
            image3: singleProduct['image3'],
            childCategoryId: singleProduct['childCategoryId']));
      });
      return products;
    } else {
      throw Exception('error fetching posts');
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,现在我想添加filter item,所以我创建新事件

class FilterProductEvent extends ProductsEvent {
  String childCategoryId, categoryId;
  FilterProductEvent({this.childCategoryId,@required this.categoryId});

  @override
  List<Object> get props => null;
}
Run Code Online (Sandbox Code Playgroud)

然后我创建新状态

class ProductsFiltered extends ProductsState {
  final List<Products> product;
  final bool hasReachedMax;
  final String filter;

  const ProductsFiltered({
    this.product,
    this.hasReachedMax,
    this.filter
  });

  ProductsFiltered copyWith({
    List<Products> product,
    bool hasReachedMax,
  }) {

    return ProductsFiltered(
      product: product ?? this.product,
      hasReachedMax: hasReachedMax ?? this.hasReachedMax,
    );
  }

  @override
  List<Object> get props => [product, hasReachedMax];

  @override
  String toString() =>
      'PostLoaded { product: ${product.length}, hasReachedMax: $hasReachedMax }';
}
Run Code Online (Sandbox Code Playgroud)

在里面mapEventToState我添加condition

@override
  Stream<ProductsState> mapEventToState(ProductsEvent event) async* {
    final currentState = state;
    print(event);
    print(state);
    if (event is FetchProductsEvent && !_hasReachedMax(currentState)) {
      String categoryId = event.categoryId;
      try {
        if (currentState is InitialProductsState) {
          final posts = await _fetchProducts(categoryId, 0, 3);
          yield ProductsLoaded(product: posts, hasReachedMax: false);
          return;
        }

        if (currentState is ProductsLoaded) {
          final posts =
              await _fetchProducts(categoryId, currentState.product.length, 6);
          yield posts.isEmpty
              ? currentState.copyWith(hasReachedMax: true)
              : ProductsLoaded(
                  product: currentState.product + posts,
                  hasReachedMax: false,
                );
        }
      } catch (e) {
        print(e.toString());
        yield ProductsError();
      }
    }
    else if (event is FilterProductEvent && !_hasReachedMax(currentState)) {
      String categoryId = event.categoryId;
      String childCategoryId = event.childCategoryId;
      try {
        if (currentState is InitialProductsState) {
          var posts = await _fetchProducts(categoryId, 0, 3);
          posts.where((a) => a.childCategoryId == childCategoryId).toList();

          yield ProductsFiltered(
              product: posts, hasReachedMax: false, filter: childCategoryId);
          return;
        }
        if (currentState is ProductsFiltered) {
          var posts =
              await _fetchProducts(categoryId, currentState.product.length, 6);
          var oldPost = currentState.product;
          oldPost.where((a) => a.childCategoryId == childCategoryId).toList();
          yield posts.isEmpty
              ? currentState.copyWith(hasReachedMax: true)
              : ProductsFiltered(
                  product: oldPost + posts,
                  hasReachedMax: false,
                  filter: childCategoryId);
        }
      } catch (e) {
        print(e.toString());
        yield ProductsError();
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

然后从我的用户界面中,我这样做

productBloc.add(FilterProductEvent(
                        categoryId: widget.categoryId,
                        childCategoryId:
                            state.childCategory[index].categoryId));
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我的数据列表没有被过滤。我该如何解决它?我错过了什么 ?

duo*_*dt3 -2

我认为这里的问题是过滤后再次缺少设置的帖子。

尝试一下:

var posts = await _fetchProducts(categoryId, 0, 3);
posts = posts.where((a) => a.childCategoryId == childCategoryId).toList();
Run Code Online (Sandbox Code Playgroud)