【问题标题】:Why adding data in Flutter Sink is not working?为什么在 Flutter Sink 中添加数据不起作用?
【发布时间】:2020-04-17 09:37:54
【问题描述】:

目的很简单。获取数据后,它可以通过特定的字符串集进行过滤。因此,我最初使用“全部”进行过滤,这意味着显示所有数据,并在单击任何选择芯片时,然后根据该特定字符串进行过滤。一切正常,除了从 api 调用加载后不显示所有数据。即使我再次热重载它也会显示完整的列表数据。所以基本上在 Sink 中添加字符串数据是行不通的。我想我犯了一些愚蠢的错误,但无法弄清楚。需要建议。

BLOC类

final Application _application;

ProductListScreenBloc(this._application);
int totalPages = 1;


final _productList = BehaviorSubject<List<Product>>();
Observable<List<Product>> _filteredProductList = Observable.empty();
final _filterName = BehaviorSubject<String>();


Stream<List<Product>> get productList => _productList.stream;
Stream<List<Product>> get filteredProductList => _filteredProductList;
Sink<String> get filterName => _filterName;


void loadBrandWiseProductList(
  String categorySlug, String brandSlug, int pageNo) {

if (totalPages >= pageNo) { //for pagination

  StreamSubscription subscription = _application.productListRepository
      .getBrandWiseProductList(categorySlug, brandSlug, pageNo)
      .listen((ProductListResponse response) {
    if (_productList.value == null) {

      totalPages = response.totalPage;
      _productList.add(response.productList);

      filterName.add('all');

      _filteredProductList = Observable.combineLatest2(
              _filterName, _productList, applyModelFilter)
          .asBroadcastStream();
    } 
  });

  }
 }

List<Product> applyModelFilter(
String filter,
List<Product> products,
) {
if (filter == 'all') {
  return products;
} else {
  return products
      .where((seriesSLug) => seriesSLug.series.slug == filter)
      .toList();
 }
}

UI 小部件类

 class _AllSeriesModelListScreenState extends State<AllSeriesModelListScreen> {
 AllSeriesModelListScreenArguments allSeriesModelListScreenArguments;

 ProductListScreenBloc bloc;

 int _selectedSeriesChipValue = -1;
 int _pageNo = 1;

 @override
 void initState() {
 super.initState();
 }

 @override
 void dispose() {
 super.dispose();
 bloc.dispose();
}

@override
Widget build(BuildContext context) {
RouteSettings settings = ModalRoute.of(context).settings;
allSeriesModelListScreenArguments = settings.arguments;

_init();

return Scaffold(
  body: CustomScrollView(
    slivers: <Widget>[
      StreamBuilder(
          stream: bloc.filteredProductList,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              List<Product> productList = snapshot.data;

              return SliverPadding(
                padding: EdgeInsets.symmetric(
                  vertical: 8.0,
                  horizontal: 10.0,
                ),
                sliver: SliverGrid(
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 3,
                    crossAxisSpacing: 0.0,
                    mainAxisSpacing: 8.0,
                  ),
                  delegate: SliverChildListDelegate(
                    buildModelGridList(productList),
                  ),
                ),
              );
            } else {
              return SliverList(
                delegate: SliverChildListDelegate([
                  PaddingWithTitle(
                    title: 'No Model Available',
                  ),
                ]),
              );
            }
          })
    ],
  ),
 );
}

void _init() {
 if (null == bloc) {
  bloc = ProductListScreenBloc(
    AppProvider.getApplication(context),
  );

  bloc.loadBrandWiseProductList(
      allSeriesModelListScreenArguments.categorySlug,
      allSeriesModelListScreenArguments.brandSlug,
      _pageNo);

   }
  }
}

【问题讨论】:

    标签: flutter dart rxdart


    【解决方案1】:

    我相信你在这两行中遗漏了一些东西。

    final _filterName = BehaviorSubject<String>();
    Sink<String> get filterName => _filterName;
    

    您没有暴露水槽。 BehaviorSubject 只是一个带有默认值的 StreamController 和最后一个值的缓存。因此,作为每个 Stream 控制器,它都有 2 个 props - sink 和 stream。要推送您需要访问接收器的数据。 为此,您需要输入

    StreamSink<String> get filterName => _filterName.sink;
    

    另外,为什么您在行为主题中没有种子值? 它需要有那个“默认”值

    final _filterName = BehaviorSubject<String>(seedValue: '');
    

    【讨论】:

    • 我已经尝试过使用seedvalue/没有seedvalue。还更改了接收器选项。它只是第一次不起作用。其他明智的选择芯片过滤工作正常。即使我只是热重载,它也会显示数据。所以我认为我在收听/广播 Observables 时做错了。但想不通。
    【解决方案2】:

    只需要把代码改成这个

    void loadBrandWiseProductList(
    String categorySlug, String brandSlug, int pageNo) {
    
    if (totalPages >= pageNo) { //for pagination
    
    StreamSubscription subscription = _application.productListRepository
      .getBrandWiseProductList(categorySlug, brandSlug, pageNo)
      .listen((ProductListResponse response) {
    if (_productList.value == null) {
    
      totalPages = response.totalPage;
      _productList.add(response.productList);
    
    } 
    _filteredProductList = Observable.combineLatest2(
              _filterName, _productList, applyModelFilter)
          .asBroadcastStream();
      });
    
     }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-07-24
      • 2018-12-17
      • 2020-01-19
      • 1970-01-01
      • 2022-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多