Flutter Bloc 如何从 Widget 本身更新 BlocBuilder 中的 Widget?

Posted

技术标签:

【中文标题】Flutter Bloc 如何从 Widget 本身更新 BlocBuilder 中的 Widget?【英文标题】:Flutter Bloc How to update Widget in BlocBuilder from the Widget itself? 【发布时间】:2021-04-23 01:10:51 【问题描述】:

如何使用 Slider 从 bloc Widget 本身更新 Bloc 小部件?

图表数据的事件是从另一个小部件执行的。 获取数据后,此 Widget 将打开。 当我更改滑块时,我希望图表随日期更新,但保留其他数据。 再次获取所有数据会太多。

我怎样才能只访问从同一个小部件更改的数据?

我有以下 Bloc Builder Widget、bloc_event、bloc 和 bloc_state

小部件:

class ChartWidget extends StatelessWidget 
ChartWidget(Key key) : super(key: key);

@override
Widget build(BuildContext context) 

double valueSliderDate;
return BlocBuilder<ChartDataBloc, ChartDataState>(
  builder: (context, state) 
    if (state is ChartDataLoadInProgress) 
      return LoadingIndicator();
     else if (state is ChartDataLoadSuccess) 
      final chartData = state.chartData;
      final maxValueAll = getMaxValueAll(chartData);
      final List<double> dates = getValuesDate(chartData);
      valueSliderDate = dates.first;

      return Column(children: <Widget>[
        
        Expanded(
          child: MyFancyChart(chartData, valueSliderDate),
        ),
        Slider(
          min: dates.first,
          max: dates.last,
           divisions: dates.length,
           value: valueSliderDate,
          onChanged: (value) 
            context.read<ChartDataBloc>().add(DateSliderSet(value));
          ,
        ),
      ]);
     else 
      return Container();
    
  ,
);

这是包含两个事件的 bloc_event:

abstract class ChartDataEvent 
const ChartDataEvent();
@override
List<Object> get props => [];  

class SpecificIndicatorIdSet extends ChartDataEvent 
const SpecificIndicatorIdSet(this.indicator);
final Indicator indicator;

@override
List<Object> get props => [indicator];  

class DateSliderSet extends ChartDataEvent 
const DateSliderSet(this.dateSlider);
final double dateSlider;

@override
List<Object> get props => [dateSlider];  

这是集团本身:

class ChartDataBloc extends Bloc<ChartDataEvent, ChartDataState> 
final ChartDataRepository chartDataRepository;
ChartDataBloc(@required this.chartDataRepository) : super(ChartDataLoadInProgress());

@override
Stream<ChartDataState> mapEventToState(ChartDataEvent event) async* 
if (event is SpecificIndicatorIdSet) 
yield* _mapIndicatorsLoadedToState(event);
 else if (event is DateSliderSet) 
yield* _mapDateSliderToState(event);      

Stream<ChartDataState> _mapDateSliderToState(
  DateSliderSet event
  ) async* 
try 
  final dateSlider = event.dateSlider;
  yield DateSliderLoadSuccess(
    dateSlider,
  );
 catch (_) 
  yield DateSliderLoadFailure();     

Stream<ChartDataState> _mapIndicatorsLoadedToState(
  SpecificIndicatorIdSet event
  ) async* 
try 
  final chartData = await this.chartDataRepository.loadChartData(event.indicator.id);
  yield ChartDataLoadSuccess(
    sortToListOfLists(chartData),
    event.indicator.name
  );
 catch (_) 
  yield ChartDataLoadFailure();      

这是 bloc_state:

abstract class ChartDataState 
const ChartDataState();
@override
List<Object> get props => [];  

class ChartDataLoadInProgress extends ChartDataState 

class ChartDataLoadSuccess extends ChartDataState 
final List<List<ChartData>> chartData;
final String titleIndicator;
const ChartDataLoadSuccess(this.chartData,this.titleIndicator);

@override
List<Object> get props => [chartData, titleIndicator];

@override
String toString() => 'ChartDataLoadSuccess  topics: ' + chartData + ' ';  

class ChartDataLoadFailure extends ChartDataState 

class DateSliderLoadSuccess extends ChartDataState 
final double dateSlider;
const DateSliderLoadSuccess(this.dateSlider);

@override
List<Object> get props => [dateSlider];

@override
String toString() => 'DateSliderLoadSuccess  dateSlider: ' + dateSlider.toString() + ' ';  


class DateSliderLoadFailure extends ChartDataState 

提前致谢

【问题讨论】:

您是否尝试过在您的块中创建一个变量来存储原始数据?您将能够存储数据并能够继续使用您的区块并更新您的小部件 是的,这成功了!我在 bloc 中为 Slider 创建了一个变量,然后它起作用了。 我刚刚添加它作为答案。如果你能接受,那就太好了! ?????? 【参考方案1】:

您是否尝试过在您的块中创建一个变量来存储原始数据?

您将能够存储数据并能够继续使用您的区块并更新您的小部件。

【讨论】:

以上是关于Flutter Bloc 如何从 Widget 本身更新 BlocBuilder 中的 Widget?的主要内容,如果未能解决你的问题,请参考以下文章

flutter_bloc 的 BlocBuilder 能否避免重建 Widget 的未更改部分?

如何在新版本中访问 Flutter BLoC 状态值?

如何在 Widget 之外调度 Bloc 事件?

Dart/Flutter 中 BLoC 模式的最佳实践

在 Flutter 中,有没有像 root Saga 这样的 root BLoC 模式?

尝试从 youtube-search-tutorial 实现 BLoC 时出现颤振错误