mapEventToState仅触发一次 [英] mapEventToState triggers one time only

查看:149
本文介绍了mapEventToState仅触发一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What am I doing wrong here that my state in a Bloc Pattern changes only one time then mapEventToState doesn't react to BlocProvider.of<CounterBloc>(context).add(ActiveEvent()); request?

我正在尝试使用Bloc模式,但是当我在计数器页面上的切换器中切换状态时,状态会更改,此后它根本不会更新.就像onChanged开关功能不再做任何事情一样.

I am trying to get into the way of things with the Bloc Pattern but when I switch state in the switcher on a counter page the state changes and after that, it doesn't update at all. It's like don't go any further from onChanged switch function.

我想问题出在我的流订阅中,该订阅是在CounterBloc承包商中实现的.否则我会错误地返回状态.

I guess the issue is in my stream subscription which is implemented in the CounterBloc contractor. Or I return the state incorrectly.

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

I would appreciate your help and if you explain to me the mistake.

我的阵营

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);
}

bloc事件

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 {}

counterPage

counterPage

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}');
                    },
                  )
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

推荐答案

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

Basically instead of yielding * _counterStream you need to yield the states in this i.e. Active or Inactive

更改此


    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);
    }

这篇关于mapEventToState仅触发一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆