如何使用bloc过滤列表?

时间:2019-12-13 02:56:37

标签: flutter

所以,这是集团(ref 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');
    }
  }
}

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

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

  @override
  List<Object> get props => null;
}

然后我创建新状态

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 }';
}

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();
      }
    }
  }

然后从我的用户界面中执行此操作

productBloc.add(FilterProductEvent(
                        categoryId: widget.categoryId,
                        childCategoryId:
                            state.childCategory[index].categoryId));

当我运行它时,我的数据列表未过滤。我该如何解决?我想念什么吗?

2 个答案:

答案 0 :(得分:0)

我认为这里的问题是您过滤后再次丢失了设置帖子。

尝试一下:

var posts = await _fetchProducts(categoryId, 0, 3);
posts = posts.where((a) => a.childCategoryId == childCategoryId).toList();

答案 1 :(得分:0)

您可以通过两种方式进行搜索

  • 从服务器端:   您必须设计API以根据搜索查询返回结果。
  • 通过应用程序:   您只需执行api调用1st并将其存储在bloc中,然后进行搜索即可创建一个方法,该方法将返回搜索到的列表。

    List search(keyword){ return list.where((item)=>item.contains(keyword)).toList(); }