为什么在 Flutter Sink 中添加数据不起作用?
Why adding data in Flutter Sink is not working?
目的很简单。获取数据后,可以通过特定的字符串集对其进行过滤。所以我最初使用 'all' 进行过滤,这意味着显示所有数据,当单击任何选择芯片时,然后根据该特定字符串进行过滤。一切正常,除了从 api 调用加载数据后不显示所有数据。即使我再次热重载,它也会显示完整的列表数据。所以基本上在 Sink 中添加字符串数据是行不通的。我想我犯了一些愚蠢的错误,但无法弄清楚。需要建议。
集团Class
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
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);
}
}
}
我相信您错过了这两行中的某些内容。
final _filterName = BehaviorSubject<String>();
Sink<String> get filterName => _filterName;
你没有暴露水槽。 BehaviorSubject 只是一个具有默认值和最后一个值缓存的 StreamController。因此,对于每个 Stream 控制器,它都有 2 个 props - sink 和 stream。要推送数据,您需要访问接收器。
为此,您需要输入
StreamSink<String> get filterName => _filterName.sink;
另外为什么你在行为主题中没有种子值?
必须具有 "default" 值
final _filterName = BehaviorSubject<String>(seedValue: '');
只好把代码改成这样
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();
});
}
}
目的很简单。获取数据后,可以通过特定的字符串集对其进行过滤。所以我最初使用 'all' 进行过滤,这意味着显示所有数据,当单击任何选择芯片时,然后根据该特定字符串进行过滤。一切正常,除了从 api 调用加载数据后不显示所有数据。即使我再次热重载,它也会显示完整的列表数据。所以基本上在 Sink 中添加字符串数据是行不通的。我想我犯了一些愚蠢的错误,但无法弄清楚。需要建议。
集团Class
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
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);
}
}
}
我相信您错过了这两行中的某些内容。
final _filterName = BehaviorSubject<String>();
Sink<String> get filterName => _filterName;
你没有暴露水槽。 BehaviorSubject 只是一个具有默认值和最后一个值缓存的 StreamController。因此,对于每个 Stream 控制器,它都有 2 个 props - sink 和 stream。要推送数据,您需要访问接收器。 为此,您需要输入
StreamSink<String> get filterName => _filterName.sink;
另外为什么你在行为主题中没有种子值? 必须具有 "default" 值
final _filterName = BehaviorSubject<String>(seedValue: '');
只好把代码改成这样
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();
});
}
}