【问题标题】:Flutter debounce api call in rxdart vanilla blocrxdart vanilla bloc中的Flutter debounce api调用
【发布时间】:2021-02-19 23:14:54
【问题描述】:

我有一个香草集团,我正在实施无限列表视图。到目前为止,我已经做到了。这是我的 bloc 实现,我将数据加载到这样的无限列表视图中。

class MyProductsBloc {
  final MyProductsRepo _repository = MyProductsRepo();
  final BehaviorSubject<MyProducts> _subject = BehaviorSubject<MyProducts>();
  int _page;
  getMyProducts() async {
    _page = 1;
    MyProducts response = await _repository.getProducts(page: 1);
    _subject.sink.add(response);
  }

  getMoreProducts() async {
    _page++;
    MyProducts response =
        await _repository.getProducts(page: _page);
    if (response.success) {
      _subject.value.maxPage = response.maxPage;
      _subject.value.pageNum = response.pageNum;
      _subject.value.data.addAll(response.data);
      _subject.sink.add(_subject.value);
    } else {
      _page--;
    }
  }

  dispose() {
    _subject?.close();
  }

  BehaviorSubject<MyProducts> get subject => _subject;
}

在 UI 部分,我使用的是 streambuilder,它有一个带有通知列表的列表视图来监听滚动通知。

StreamBuilder<MyProducts>(
                stream: myProductsBloc.subject.stream,
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    if (snapshot.data.error != null &&
                        snapshot.data.error.length > 0) {
                      return ShowError(
                        error: snapshot.data.error,
                        onTap: () => myProductsBloc.getMyProducts(),
                      );
                    } else if (snapshot.data.data.length == 0) {
                      return EmptyWidget();
                    }
                    return NotificationListener<ScrollNotification>(
                      onNotification: (ScrollNotification scrollInfo) {
                        if (scrollInfo.metrics.pixels ==
                            scrollInfo.metrics.maxScrollExtent) {
                          if (snapshot.data.isEnd) {
                            return false;
                          } else {
                            myProductsBloc.getMoreProducts();
                          }
                        }
                        return false;
                      },
                      child: ListView(
                        children: [
                          ListView.separated(
                            primary: false,
                            shrinkWrap: true,
                            separatorBuilder: (context, i) =>
                                const SizedBox(height: 10),
                            padding: EdgeInsets.all(10),
                            itemCount: snapshot.data.data.length,
                            itemBuilder: (context, i) {
                              ProductData productData = snapshot.data.data[i];
                              return ProductCard(product: productData);
                            },
                          ),
                          LoadMoreIndicator(isEnd: snapshot.data.isEnd),
                        ],
                      ),
                    );
                  } else if (snapshot.hasError) {
                    return Center(
                      child: Text('${snapshot.data.error}'),
                    );
                  } else {
                    return Center(
                        child: LoadingWidget(text: "Fetching products.."));
                  }
                }),

但是当滚动时,api 被多次调用。有什么办法可以在这种模式下多次调用 api 去抖动?

【问题讨论】:

    标签: flutter dart rxdart


    【解决方案1】:
    
    
    class MyProductsBloc {
      var _isLoading = false; <---- add this variable
    
      final MyProductsRepo _repository = MyProductsRepo();
      final BehaviorSubject<MyProducts> _subject = BehaviorSubject<MyProducts>();
      int _page;
      getMyProducts() async {
        _page = 1;
        MyProducts response = await _repository.getProducts(page: 1);
        _subject.sink.add(response);
      }
    
      getMoreProducts() async {
        if (_isLoading) return;
        _isLoading = true;
       
        try {
            _page++;
            MyProducts response = await _repository.getProducts(page: _page);
           if (response.success) {
             _subject.value.maxPage = response.maxPage;
             _subject.value.pageNum = response.pageNum;
             _subject.value.data.addAll(response.data);
             _subject.sink.add(_subject.value);
           } else {
             _page--;
           }
        } finally { _isLoading = false; }
      }
    
      dispose() {
        _subject?.close();
      }
    
      BehaviorSubject<MyProducts> get subject => _subject;
    }
    

    【讨论】:

    • 谢谢。它可以工作,但有时会卡在加载中。我猜我可以忍受:)
    • @ZeroLive 试试 catch _repository.getProducts(page: _page)。更新答案:)
    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 2020-01-26
    • 2021-01-06
    • 2019-10-05
    • 2021-07-14
    • 2016-08-01
    • 2022-08-19
    • 2020-07-23
    相关资源
    最近更新 更多