Думаю, теперь я вижу, что происходит с transform()
в Bloc.dart
классе. ScanStreamTransformer внутри конструктора BloC.dart
вызывается один раз для каждого прослушивателя (внутри класса One.dart
есть 3 слушателя, поэтому он вызывается 3 раза). Я хотел бы изменить это поведение, чтобы оно вызывалось один раз для каждого события, независимо от того, сколько слушателей подключено, например. вызов _mainBloc.inValue(widget.value)
вызовет преобразование только один раз, сейчас он вызывается 3 раза, потому что внутри функции One.dart
build() есть 3 слушателя (см. streamBuilder()
).
Я надеюсь, что это немного яснее по сравнению с предыдущим сообщением (теперь удалено).
class OneState extends State<One>{
@override
void didChangeDependencies() {
super.didChangeDependencies();
_mainBloc.inValue(widget.value);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: <Widget>[
streamBuilder(),
streamBuilder(),
streamBuilder()
],
),
);
}
streamBuilder(){
return StreamBuilder(
stream: _mainBloc.values$,
builder: (context, AsyncSnapshot<Map<String, Future<String>>> snapshot){
if(snapshot.connectionState == ConnectionState.waiting) return Center(child: Container(child: new CircularProgressIndicator()));
if(!snapshot.hasData) return Center(child: Container(child: Text("No Data"),));
return FutureBuilder(
future: snapshot.data[widget.value],
builder: (contextFuture, AsyncSnapshot<String> snapshotFuture){
if(snapshotFuture.connectionState == ConnectionState.waiting)
return Center(child: Container(child: new CircularProgressIndicator()));
return Center(
child: Container(
child: Text(snapshotFuture.data),
),
);
},
);
},
);
}
}
блок
class MainBloc{
final ApiRequest _provider;
MainBloc(this._provider){
values$ = _value.stream.transform(
ScanStreamTransformer((Map<String, Future<String>> cache, String symbol, index){
print('transformer');
cache[symbol] = _provider.fetchData();
return cache;
},
<String, Future<String>>{},
));
}
final _value = BehaviorSubject<String>();
Observable<Map<String, Future<String>>> values$;
Function(String symbol) get inValue => _value.sink.add;
dispose(){
_value.close();
}
}
StreamBuilder
+FutureBuilder
? чего вы хотите достичь? может бытьScanStreamTransformer
это не то, что вам действительно нужно? - person pskink   schedule 28.11.2019snapshotFuture.data[username]
и это, кажется, отображает все данные для конкретного пользователя. - person Jamie White   schedule 28.11.2019SteeamBuilder
и предоставить правильныйStream
, который предоставляет ваши полные данные (а не промежуточныеFuture
) - person pskink   schedule 28.11.2019asyncMqp
или подобные меры - person pskink   schedule 28.11.2019asyncMap
, так как это практически то же самое, что и методmap
- единственная разница в том, что он может быть асинхронным, что означает, что функция сопоставления может возвращатьFuture
- person pskink   schedule 28.11.2019StreamBuilder
, и любые вещи, связанные с данными (например, преобразование асинхронного потока), должны выполняться в вашей модели данных (я имею в виду в вашем BLoC, а не внутри вложенногоFutureBuilder
), простой пример: pastebin.com/GziDTpNC — здесьswitchMap
используется вStreamBuilder
, но все зависит от того, как вы хотите обрабатывать свои данные. - проверьте, например,asyncMap
/flatMap
/concatMap
, а также - person pskink   schedule 29.11.2019"What you suggest does not work. The only method that seems prevent the data from being mixed is the above"
- сейчас работает? Вы пробовали нажимать кнопки элемента #x и видеть текст выше? - person pskink   schedule 30.11.2019