是否可以使用具有通用状态的抽象肘节?

问题描述 投票:0回答:1

我陷入了使用通用类型作为 Cubit 状态的问题。问题在于 Cubit 状态的不变性以及无法为泛型类型调用

copyWith
。基于 ChangeNotifier 的类似实现不会导致问题,因为我们可以改变返回的状态。

例如,我创建了一个具有通用状态的基本 Cubit,我计划对其进行扩展。然后我通过添加一个字段和 copyWith() 来实现通用类型的肘状态。

abstract class BasePageCubit<TParams extends BasePageParams>
    extends Cubit<TParams> {
  BasePageCubit({
    required TParams initialState,
  }) : super(initialState);

  @mustCallSuper
  void initialise() {
    emit(state);
  }

  @protected
  void markLoaded() {
    emit(
      **state.copyWith(isLoading: false)**,
    );
  }
}


@CopyWith()
class DataParams<TData> extends BasePageParams {
  TData data;

  DataParams({
    required this.data,
    super.isLoading = true,
    super.pageError,
  });
}

显然,我不能在 BasePageCubit 中使用

state.copyWith(isLoading: false)
,但我没有看到任何其他方法来实现与从 BasePageCubit 继承的 Cubit 一起使用的可扩展逻辑。一般来说,无论可用的类字段如何,我都需要通用 copyWith() 。这是 Dart 类型系统的基本限制,还是有任何解决方法?也许我误解了带有继承的 Bloc 模式?

flutter dart generics bloc flutter-bloc
1个回答
0
投票

我使用

Equatable
而不是
@CopyWith
注释。

使用下面的代码将允许您拥有通用状态。

abstract class BasePageCubit<TData> extends Cubit<DataParams<TData>> {
  BasePageCubit({
    required DataParams<TData> initialState,
  }) : super(initialState);

  void initialise() {
    emit(state);
  }

  void markLoaded() {
    emit(state.copyWith(isLoading: false));
  }
}

class DataParams<TData> extends BasePageParams {
  final TData data;

  const DataParams({
    required super.isLoading,
    required this.data,
    super.pageError,
  });

  @override
  DataParams<TData> copyWith({
    TData? data,
    bool? isLoading,
    String? pageError,
  }) {
    return DataParams(
      data: data ?? this.data,
      isLoading: isLoading ?? this.isLoading,
      pageError: pageError ?? this.pageError,
    );
  }

  @override
  List<Object?> get props => [data, isLoading, pageError];
}

abstract class BasePageParams extends Equatable {
  final bool isLoading;
  final String? pageError;

  const BasePageParams({
    required this.isLoading,
    this.pageError,
  });

  BasePageParams copyWith({
    bool? isLoading,
    String? pageError,
  });

  @override
  List<Object?> get props;
}
© www.soinside.com 2019 - 2024. All rights reserved.