【问题标题】:Flutter BLoC : how to update state with null values?Flutter BLoC:如何使用空值更新状态?
【发布时间】:2022-08-21 14:49:24
【问题描述】:

当您更新 BLoC 中的状态时,您如何处理“接受的空值”? 我使用 flutter_bloc 包。

我有一个表格,其中数字变量可以为空,以便我可以在提交表格之前检查它们的有效性。 但是当我发出一个新状态时,我使用 state.copyWith(var1?, var2?)... 所以当使用空值更新参数时,该值不会更新。

面对这一点,我为每个字段使用自定义 FieldStatus 枚举。在我的表单提交中,我可以检查每个字段的状态。但这有点冗长......并且它需要为每个字段使用 2 个值而不是 1,这不是很令人满意。

我也可以根据它的FieldStatus的新值强制该值为null,但是有点棘手,不是很满意。

您将如何处理这种情况?

这是我所做的:

状态 :

part of \'phhfgroup_bloc.dart\';

class PhhfGroupState extends Equatable
{
    final double? height;
    final FieldStatus heightStatus;
    
    const PhhfGroupState({this.height, this.heightStatus = FieldStatus.initial});
    
    @override
    List<Object?> get props => [height, heightStatus];
    
    PhhfGroupState copyWith({double? height, FieldStatus? heightStatus})
    {
        return PhhfGroupState(
            height: height ?? this.height,
            heightStatus: heightStatus ?? this.heightStatus
        );
    }
}

活动:

part of \'phhfgroup_bloc.dart\';

abstract class PhhfGroupEvent extends Equatable
{
    const PhhfGroupEvent();
    
    @override
    List<Object> get props => [];
}

class HeightChanged extends PhhfGroupEvent
{
    const HeightChanged({required this.height});
    final String height;

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

处理程序:

import \'package:equatable/equatable.dart\';
import \'package:flutter_bloc/flutter_bloc.dart\';
import \'package:myapp/models/statuses.dart\';

part \'phhfgroup_event.dart\';
part \'phhfgroup_state.dart\';

class PhhfGroupBloc extends Bloc<PhhfGroupEvent, PhhfGroupState>
{
    PhhfGroupBloc() : super()
    {
        on<HeightChanged>(_mapHeightEventToState);
    }
    
    void _mapHeightEventToState(HeightChanged event, Emitter<PhhfGroupState> emit)
    {
        if(event.height.isEmpty)
        {
            emit(this.state.copyWith(
                height: null,
                heightStatus: FieldStatus.empty
            ));
        }
        
        else
        {
            double? height = double.tryParse(event.height);
            
            if(height == null)
                emit(this.state.copyWith(
                    height: null,
                    heightStatus: FieldStatus.nonnumeric
                ));
            
            else emit(this.state.copyWith(
                height: height,
                heightStatus: FieldStatus.numeric
            ));
        }
    }
}

谢谢 !

    标签: flutter dart null bloc flutter-bloc


    【解决方案1】:

    通过使用freeze,您可以执行以下操作:

    void main() {
      var person = Person('Remi', 24);
    
      // `age` not passed, its value is preserved
      print(person.copyWith(name: 'Dash')); // Person(name: Dash, age: 24)
      // `age` is set to `null`
      print(person.copyWith(age: null)); // Person(name: Remi, age: null)
    }
    

    如果您不想使用另一个包,我建议添加一个用于控制可空值的参数。

    class PhhfGroupState extends Equatable
    {
        final double? height;
        final FieldStatus heightStatus;
        
        const PhhfGroupState({this.height, this.heightStatus = FieldStatus.initial});
        
        @override
        List<Object?> get props => [height, heightStatus];
        
        PhhfGroupState copyWith({double? height, FieldStatus? heightStatus, bool clearHeight = false})
        {
            return PhhfGroupState(
                height: clearHeight == true ? null : height ?? this.height,
                heightStatus: heightStatus ?? this.heightStatus
            );
        }
    }
    

    如果你有一堆nullable 字段,我强烈推荐freeze,但对于其他人,只需为它添加一个标志。

    【讨论】:

      【解决方案2】:

      非常感谢,因为这正是我所需要的!避免大量样板代码来实现这个简单的目标......

      所以为了实现我需要的东西,我将使用:

      • 冻结以帮助管理状态/事件
      • 我的 FieldStatus 枚举使一些信息在视图中可用

      【讨论】:

        【解决方案3】:

        另一种方式,你可以使用ValueGetter.

        例如下面的password

        @immutable
        class LoginPageState {
          const LoginPageState({
            this.phone,
            this.password,
          });
        
          final String? phone;
          final String? password;
        
          LoginPageState copyWith({
            String? phone,
            ValueGetter<String?>? password,
          }) {
            return LoginPageState(
              phone: phone ?? this.phone,
              password: password != null ? password() : this.password,
            );
          }
        }
        

        password 设置为null

        void resetPassword() {
          final newState = state.copyWith(password: () => null);
          emit(newState);
        }
        

        你不需要任何额外的标志。

        【讨论】:

          猜你喜欢
          • 2021-03-19
          • 2021-07-24
          • 2020-10-10
          • 2021-07-27
          • 2020-02-27
          • 2021-08-02
          • 2020-09-03
          • 2022-08-11
          • 2020-09-16
          相关资源
          最近更新 更多