【问题标题】:How to manage different States in the same Bloc? Flutter如何管理同一集团中的不同国家?扑
【发布时间】:2021-12-23 00:23:24
【问题描述】:

我试图在我的应用程序中处理 3 种不同的状态,在我家的 initState 中,我将事件称为“OnInitial”,假装是从本地数据库获取数据的方法。

正如您在方法中看到的那样,我将“6”设置为变量“数字”,就像我说的那样,假装这将是我从数据库中带来的数据。我的事件完成获取数据并发出状态“ProductsTercero”已经“分配的数据”。

在我的家中,如果状态是 ProductsTercero,我会用“msg”和“number”绘制一个列。 当初始完成时,我的屏幕被正确重绘并显示

但我的问题如下。当我按下触发事件“OnTercero”的名为“Tercero”的按钮时 在我的 Bloc 中,当调用此事件时,它会将“New msg”设置为 ProducsTercero 的变量“msg”。 这是做什么的?下一个:

它删除了我之前设置的“数字 6”,也就是说,关于模拟,我将删除我从数据库中带来的所有数据。

我的预期结果是:

New msg
6

但我得到了

New msg
0

我进行了调试,似乎它总是在创建一个新的 ProductsThird 对象。即使我做 ProductsTercero().copyWith(msg: 'New msg');是一样的。

我只使用过 1 个州,这不会发生在我身上,因为我总是做 state.copyWith();并且该状态的其他值始终保持不变,无论我是否传递了它具有的 5 个属性中的 1 个属性。但是在这里,有多个状态并且有一个抽象状态类,我不能写 emit(state.copyWith(msg: 'New msg');

我做错了什么?在 X 状态下发射的正确方法是什么并且不会发生这种情况?

事件、状态和块代码:

part of 'products_bloc.dart';

@immutable
abstract class ProductsEvent {}

class OnInitial extends ProductsEvent {}
class OnSegundo extends ProductsEvent {}
class OnTercero extends ProductsEvent {}

//**************************************************************//

part of 'products_bloc.dart';

@immutable
abstract class ProductsState {}

class ProductsInitial extends ProductsState {
  final String? msg;
  final int? numero;

  ProductsInitial({numero, msg})
      : msg = msg ?? 'MSG: Default Inicial',
        numero = numero ?? 0;
  ProductsInitial copywith({String? msg, int? numero}) =>
      ProductsInitial(msg: msg ?? this.msg, numero: numero ?? this.numero);
}

class ProductsSegundo extends ProductsState {
  final String? msg;
  final int? numero;

  ProductsSegundo({numero, msg})
      : msg = msg ?? 'Second: Default Msg',
        numero = numero ?? 0;
  ProductsSegundo copywith({String? msg, int? numero}) =>
      ProductsSegundo(msg: msg ?? this.msg, numero: numero ?? this.numero);
}

class ProductsTercero extends ProductsState {
  final String? msg;
  final int? numero;

  ProductsTercero({numero, msg})
      : msg = msg ?? 'Third: Default Msg',
        numero = numero ?? 0;
  ProductsTercero copywith({String? msg, int? numero}) =>
      ProductsTercero(msg: msg ?? this.msg, numero: numero ?? this.numero);
}


//**********************************************************//

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

part 'products_event.dart';
part 'products_state.dart';

class ProductsBloc extends Bloc<ProductsEvent, ProductsState> {
  ProductsBloc() : super(ProductsInitial()) {
    on<OnInitial>((event, emit) {
      emit(ProductsInitial().copywith(
        msg: 'Initial msg'
      ));
      emit(ProductsTercero(numero: 6));
    });


    on<OnSegundo>((event, emit) {
      emit(ProductsSegundo());
    });


    on<OnTercero>((event, emit) {
      emit(ProductsTercero(msg: 'New msg'));
    });
  }
}

首页代码:

import 'package:bloc_test/src/bloc/products/products_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  void initState() {
    BlocProvider.of<ProductsBloc>(context).add(OnInitial());
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<ProductsBloc, ProductsState>(
      builder: (context, state) {
        return Scaffold(
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              (state is ProductsInitial) ? Column(
                children: [
                  Center(child: Text(state.msg!)),
                  Center(child: Text(state.numero!.toString())),
                ],
              )
              : (state is ProductsSegundo) ? Column(
                children: [
                  Center(child: Text(state.msg!)),
                  Center(child: Text(state.numero!.toString())),
                ],
              )
              : (state is ProductsTercero) ? Column(
                children: [
                  Center(child: Text(state.msg!)),
                  Center(child: Text(state.numero!.toString())),
                ],
              )
              : Center(child: Text('Nada')),
              SizedBox(
                height: 40,
                width: double.infinity,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    ElevatedButton(
                        onPressed: () {
                          BlocProvider.of<ProductsBloc>(context).add(OnInitial());
                        },
                        child: Text('Initial')),
                    ElevatedButton(
                        onPressed: () {
                          BlocProvider.of<ProductsBloc>(context).add(OnSegundo());
                        },
                        child: Text('Segundo')),
                    ElevatedButton(
                        onPressed: () {
                          BlocProvider.of<ProductsBloc>(context).add(OnTercero());
                        },
                        child: Text('Tercero'))
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );
  }
}

【问题讨论】:

    标签: flutter state bloc flutter-bloc


    【解决方案1】:

    您没有在 emit(ProductsTercero(msg: 'New msg')); 上传递 num 值

    由于 num == null 然后它被设置为 0,由您的代码定义。

    尝试如下替换

    on<OnTercero>((event, emit) {
      emit(ProductsTercero(msg: 'New msg',numero: 6));
    });
    

    【讨论】:

    • 嗨,是的,但是如果我有一个包含 10 个变量的状态呢?在相同的情况下,我将不得不传递每个发射中的每个变量,而我实际上会在方法中更改 1。所以我认为你的回答没问题,但不是我提到的这种情况的解决方案。我还在寻找解决方案
    猜你喜欢
    • 2014-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    相关资源
    最近更新 更多