mapEventToState 仅触发一次

Posted

技术标签:

【中文标题】mapEventToState 仅触发一次【英文标题】:mapEventToState triggers one time only 【发布时间】:2020-08-25 21:33:37 【问题描述】:

我在 Bloc 模式中的状态仅更改一次然后 mapEventToStateBlocProvider.of<CounterBloc>(context).add(ActiveEvent()); 请求没有反应,我做错了什么?

我正在尝试使用 Bloc 模式来解决问题,但是当我在计数器页面上的切换器中切换状态时,状态会发生变化,之后它根本不会更新。这就像不要从onChanged切换功能进一步。

我想问题出在我在 CounterBloc 承包商中实施的流订阅中。或者我错误地返回了状态。

如果您向我解释错误,我将不胜感激。

我的集团

import 'dart:async';

import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:practicing_bloc/blocs/counter/counterEvents.dart';
import 'package:practicing_bloc/blocs/counter/counterState.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> 
  @override
  CounterState get initialState => Active(active: true, count: 0);

  CounterBloc() 
    _counterStream = _counter.stream;
  

  StreamController<CounterState> _counter = StreamController<CounterState>();
  Stream<CounterState> _counterStream;

  @override
  Stream<CounterState> mapEventToState(CounterEvent event) async* 
    CounterState currentState = state;
    print('currect: $currentState');

    if (event is ActiveEvent) 
      _counter.add(Active(active: true, count: currentState.count));
      yield* _counterStream;
     else if (event is InactiveEvent) 
      _counter.add(Inactive(active: false, count: currentState.count));
      yield* _counterStream;
    
  

集团国家

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

abstract class CounterState extends Equatable 
  final bool active;
  final int count;

  const CounterState(@required this.active, @required this.count);

  @override
  List<Object> get props => [active, count];

  @override
  String toString() => 'State  active : $active, count : $count ';


class Active extends CounterState 
  const Active(@required bool active, @required int count)
      : super(active: active, count: count);


class Inactive extends CounterState 
  const Inactive(@required bool active, @required int count)
      : super(active: active, count: count);

集体活动

import 'package:equatable/equatable.dart';

abstract class CounterEvent extends Equatable 
  const CounterEvent();

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


class Increase extends CounterEvent 
class Decrease extends CounterEvent 
class ActiveEvent extends CounterEvent 
class InactiveEvent extends CounterEvent 

计数器页面

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:practicing_bloc/blocs/counter/counterBloc.dart';

class CounterPage extends StatefulWidget 
  @override
  _CounterPageState createState() => _CounterPageState();


class _CounterPageState extends State<CounterPage> 
  bool stateActive = false;

  @override
  Widget build(BuildContext context) 
    //ignore: close_sinks
    dynamic counterBloc = BlocProvider.of<CounterBloc>(context);

    return Scaffold(
      appBar: AppBar(title: Text('Flutter Counter | Page title')),
      body: SafeArea(
        child: BlocBuilder<CounterBloc, CounterState>(
          builder: (context, state) 
            String stateString = state.active ? 'Active' : 'Inactive';

            return Center(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('Counter is : $stateString'),
                  Text('Current counter is : $state.count'),
                  Switch(
                    value: stateActive,
                    onChanged: (bool value) 
                      print(counterBloc.state);
                      setState(() 
                        stateActive = value;
                      );
                      CounterEvent newEvent =
                          value ? ActiveEvent() : InactiveEvent();
                      counterBloc.add(newEvent);
                      // print('BloC state: $counterBloc.state.active | switch state: $state.active');
                    ,
                  )
                ],
              ),
            );
          ,
        ),
      ),
    );
  

【问题讨论】:

【参考方案1】:

基本上,您需要在此产生状态而不是产生 * _counterStream,即 ActiveInactive

改变这个


    if (event is ActiveEvent) 
      _counter.add(Active(active: true, count: currentState.count));
      yield* _counterStream;
     else if (event is InactiveEvent) 
      _counter.add(Inactive(active: false, count: currentState.count));
      yield* _counterStream;
    

到这里

    if (event is ActiveEvent) 
      yield Inactive(active: false, count: currentState.count);
     else if (event is InactiveEvent) 
      yield Active(active: true, count: currentState.count);
    

【讨论】:

我以为我应该在那里返回一个流。但显然 BloCProvider 是在幕后做的,或者其他什么.. 非常感谢您的帮助,Zain!它似乎对我有用 很高兴为您提供帮助

以上是关于mapEventToState 仅触发一次的主要内容,如果未能解决你的问题,请参考以下文章

iOS UILocalNotification 设置为每天触发一次,每两天触发一次,并且仅在星期日触发

iOS Safari Mobile 不会仅触发一次页面显示触发

ComponentWillMount 仅第一次触发?

Azure 警报仅触发一次

Oracle SP 和触发器仅成功运行一次

FEventType.ChildAdded 事件仅触发一次