【问题标题】:Reset values event and state in the bloc flutter重置块颤动中的事件和状态
【发布时间】:2021-09-25 06:51:55
【问题描述】:

我将值单独赋予事件,但其他变量的值在事件中被重置。我为国家做了同样的事情。我用两个变量定义了一个状态,我通过 copyWith 在不同的地方赋予这些值但是每次发送一个离子时,状态值都会返回到它们的原始状态。 块中的状态和事件是否会在其值的每次更改中重置????

主要


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:test1/bloc/datatest_bloc.dart';
import 'package:test1/bloc/datatest_state.dart';
import 'package:test1/bloc/datatest_event.dart';

import 'bloc/datatest_bloc.dart';

main() {
  runApp(MaterialApp(
    home: BlocProvider<Databloc>(
      create: (context) => Databloc(),
      child: Home(),
    ),
  ));
}

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

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: BlocBuilder<Databloc, DatatestState>(
        builder: (context, state) {
          return Center(
            child: Column(
              children: [
                ElevatedButton(
                  onPressed: () {
                    BlocProvider.of<Databloc>(context)
                        .add(DataEvent_name().copyWith(name: 'mohammd'));
                  },
                  child: Text('btn'),
                ),
                 ElevatedButton(
                  onPressed: () {
                    BlocProvider.of<Databloc>(context)
                        .add(DataEvent_name().copyWith(pass: 'passsss'));
                  },
                  child: Text('pass'),
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

事件块

  
}

class DataEvent_name extends DatatestEvent {
  final String name;
  final String pass;
  DataEvent_name({ this.name='',  this.pass=''});

  DataEvent_name copyWith({String? name, String? pass}) {
    return DataEvent_name(name: name ?? this.name, pass: pass ?? this.pass);
  }
}

class DataEvent_pass extends DatatestEvent {}

class DataEvent_print extends DatatestEvent {}

状态类

class DatatestState {

final String name;
  final String pass;
  DatatestState({
     this.name ='',
     this.pass='',
  });
 

  DatatestState copyWith({
    String? name,
    String? pass,
  }) {
    return DatatestState(
      name: name ?? this.name,
      pass: pass ?? this.pass,
    );
  }
}

集团类

class Databloc extends Bloc<DatatestEvent, DatatestState> {
  Databloc() : super(DatatestState());

  final servisApi = ServisApi();

  @override
  Stream<DatatestState> mapEventToState(DatatestEvent event) async* {
    if (event is DataEvent_name) {
      yield DatatestState(name: event.name, pass: event.pass);
      servisApi.PrintState(a: state.name, b: state.pass);
    }
    
  }
}

输出

flutter: a:mohammd  b:
flutter: a:  b:passsss
flutter: a:mohammd  b:
flutter: a:  b:passsss
flutter: a:mohammd  b:
flutter: a:  b:passsss

【问题讨论】:

  • 你在使用 equatable 吗?
  • 是的...但是问题的存在没有解决
  • 我问是因为我没有看到你覆盖属性,这可能会导致 bloc 无法正确更新。
  • 现在我再次测试了两个事件,每个事件都改变了状态中变量的值,我使用了包 equatable 但是当我用其中一个事件更改状态变量的值时,另一个变量到国家

标签: flutter class events state bloc


【解决方案1】:

BLoC 设计模式有助于将表示层与业务逻辑分开。

Events 是 Bloc 的输入。它们通常是 UI 事件,例如按钮按下。事件被分派,然后转换为状态。

States 是 Bloc 的输出。表示组件可以侦听状态流并根据给定状态重绘自身的一部分。

Transitions 在调用 mapEventToState 之后但在更新 Bloc 状态之前调度事件时发生。一个 Transition 由 currentState、被调度的事件和 nextState 组成。

来到您展示的示例,您在 UI 中有 2 个按钮:

  1. btn :您通过仅将 Name 参数传递为“mohammd”来触发事件 DataEvent_name。因此,最终状态的值是 name:'mohammd' 和 pass:''。 由于您正在打印当前状态值,因此输出为: a:mohammd b:

  2. pass:您通过仅将 pass 参数作为“passsss”传递来触发事件 DataEvent_name。因此,最终状态的值是 name:'' 和 pass:'passsss'。由于您正在打印当前状态值,因此输出为: a: b:passsss

块中的状态和事件是否在其每次更改时重置 价值观

事件只是输入。它是 UI 数据的载体,以便在执行业务逻辑时可以获得所需的数据。 由于状态是事件的输出,因此在整个 BLoC 中,它一次只能有一个状态。因此,是的,它会更新早期的状态。 如果我们要完全重置或更新现有状态中的某些值,这取决于用例。

如何更新现有状态mapEventToState 中,我们可以使用state 变量访问当前状态。因此,在产生新状态的同时,我们也可以根据所需的用例从当前状态传递数据。

在您的示例中:如果您想保持 name 的旧值并在其空白时通过:

yield DatatestState(
          name: event.name == '' ? state.name : event.name,
          pass: event.pass == '' ? state.pass : event.pass);

它将返回以下输出:

a:mohammd b:
a:mohammd b:passsss

【讨论】:

    猜你喜欢
    • 2020-12-15
    • 2021-11-30
    • 1970-01-01
    • 2019-08-31
    • 2020-04-09
    • 2022-11-16
    • 2020-06-07
    • 2021-11-01
    • 2017-10-03
    相关资源
    最近更新 更多