English 中文(简体)
1. 拥有河床和自由河床的不同州
原标题:Merge different states with Riverpod and Freezed
  • 时间:2023-05-10 11:44:32
  •  标签:
The bounty expires in 7 hours. Answers to this question are eligible for a +100 reputation bounty.Ruble is looking for a more detailed answer to this question:
Suggest a convenient way to combine/process multiple states.

我有一个网页,需要2个不同的APIC电话。

我正在运用清洁结构来撰写该守则,并将之作为国家管理。 然后,我利用自由套线绘制各州地图。

How can I combine the different states? What I would like to achieve is to emit a success state only if both states give me data or emit an error state if one of them is an error, otherwise loading state.

提前感谢。

它们是:

import  package:freezed_annotation/freezed_annotation.dart ;
import  ...eatures/profile/domain/entities/user_profile_entity.dart ;

part  user_profile_details_state.freezed.dart ;

@freezed
class UserProfileDetailsState with _$UserProfileDetailsState {
  ///Initial
  const factory UserProfileDetailsState.initial() =
      _UserProfileDetailsStateInitial;

  ///Loading
  const factory UserProfileDetailsState.loading() =
      _UserProfileDetailsStateLoading;

  ///Data
  const factory UserProfileDetailsState.data(
      {required ProfileEntity profileEntity}) = _UserProfileDetailsStateData;

  ///Error
  const factory UserProfileDetailsState.error([String? error]) =
      _UserProfileDetailsStateError;
}
import  package:freezed_annotation/freezed_annotation.dart ;
import  ....features/profile/domain/entities/user_properties_entity.dart ;

part  user_properties_state.freezed.dart ;

@freezed
class UserPropertiesState with _$UserPropertiesState {
  ///Initial
  const factory UserPropertiesState.initial() = _UserPropertiesStateInitial;

  ///Loading
  const factory UserPropertiesState.loading() = _UserPropertiesStateLoading;

  ///Data
  const factory UserPropertiesState.data(
          {required UserPropertiesEntity userPropertiesEntity}) =
      _UserPropertiesStateData;

  ///Error
  const factory UserPropertiesState.error([String? error]) =
      _UserPropertiesStateError;
}

这些是两个通知人:

import  ...core/di/dependency_injection.dart ;
import  ...core/errors/failures.dart ;
import  ...core/presentation/riverpod/check_token_notifier.dart ;
import  ...features/profile/presentation/riverpod/user_profile_details_state.dart ;
import  package:riverpod_annotation/riverpod_annotation.dart ;

part  user_profile_details_notifier.g.dart ;

@riverpod
class UserProfileDetailsNotifier extends _$UserProfileDetailsNotifier {
  @override
  UserProfileDetailsState build() {
    getUserProfileDetailsData();
    return const UserProfileDetailsState.initial();
  }

  Future<void> getUserProfileDetailsData() async {
    state = const UserProfileDetailsState.loading();
    final userProfileDetailsOrFailure = await ref
        .read(userProfileDetailsUseCaseProvider)
        .getUserProfileDetailsData();
    userProfileDetailsOrFailure.fold((error) {
      if (error is TokenFailure) {
        ref.read(checkTokenNotifierProvider.notifier).deAuthUser();
        return;
      }
      state = UserProfileDetailsState.error(error.errorMessage);
    }, (userProfileDetailsEntity) {
      state =
          UserProfileDetailsState.data(profileEntity: userProfileDetailsEntity);
    });
  }
}
import  ...core/di/dependency_injection.dart ;
import  ...core/errors/failures.dart ;
import  ...core/presentation/riverpod/check_token_notifier.dart ;
import  ...features/profile/presentation/riverpod/user_properties_state.dart ;
import  package:riverpod_annotation/riverpod_annotation.dart ;

part  user_properties_notifier.g.dart ;

@riverpod
class UserPropertiesNotifier extends _$UserPropertiesNotifier {
  @override
  UserPropertiesState build() {
    getUserPropertiesData();
    return const UserPropertiesState.initial();
  }

  Future<void> getUserPropertiesData() async {
    state = const UserPropertiesState.loading();

    final userPropertiesOrFailure =
        await ref.read(userPropertiesUseCaseProvider).getUserPropertiesData();
    userPropertiesOrFailure.fold((error) {
      if (error is TokenFailure) {
        ref.read(checkTokenNotifierProvider.notifier).deAuthUser();
        return;
      }
      state = UserPropertiesState.error(error.errorMessage);
    }, (userPropertiesEntity) {
      state =
          UserPropertiesState.data(userPropertiesEntity: userPropertiesEntity);
    });
  }
}

问题回答

你可以建立一个单独的免税区,根据贵国的两国收集相应的新领域。 在法典中,你可以这样做:

state = CommonState.loading();

UserPropertiesState userProperties;
UserProfileDetailsState userProfileDetails;

final CommonState? state = userProperties.whenOrNull(
  orElse: () => null,
  data: (properties) => userProfileDetails.whenOrNull(
      orElse: () => null,
      data: (details) => CommonState.data(properties + details),
  ),
);

if (state == null) {
  // same with repeat with error
}

您可使用<代码> 当OrNul时所需的领域,或分成下列领域:

如果两个不同的通知国都有数据或错报国家,如果其中一个错误的话,你可以使用ProviderContainer听取两国的意见,并相应更新一个新的国家。 下面是你如何做到这一点的一个例子: 第一,创建新的州级,代表国家:

import  package:freezed_annotation/freezed_annotation.dart ;
import  ...features/profile/domain/entities/user_profile_entity.dart ;
import  ...features/profile/domain/entities/user_properties_entity.dart ;

part  combined_states.freezed.dart ;

@freezed
class CombinedStates with _$CombinedStates {
  ///Loading
  const factory CombinedStates.loading() = _CombinedStateLoading;

  ///Data
  const factory CombinedStates.success({
    required ProfileEntity profileEntity,
    required UserPropertiesEntity userPropertiesEntity,
  }) = _CombinedStateSuccess;

  ///Error
  const factory CombinedStates.error([String? error]) = _CombinedStateError;
}

其次,创建新的公证人,将两个州合并为。 用户ProfileDetailsNotifierUserProperties Notifier:

import  ...core/presentation/riverpod/check_token_notifier.dart ;
import  ...features/profile/presentation/riverpod/user_profile_details_state.dart ;
import  ...features/profile/presentation/riverpod/user_properties_state.dart ;
import  path/to/combined_states.dart ;
import  package:riverpod_annotation/riverpod_annotation.dart ;

final combinedNotifierProvider =
    Provider<CombinedNotifier>((ref) => CombinedNotifier(ref.read));

class CombinedNotifier extends StateNotifier<CombinedStates> {
  final Reader _read;

  late final UserProfileDetailsNotifier _userProfileDetailsNotifier;
  late final UserPropertiesNotifier _userPropertiesNotifier;

  CombinedNotifier(this._read) : super(const CombinedStates.loading()) {
    _userProfileDetailsNotifier =
        _read(userProfileDetailsNotifierProvider.notifier);
    _userPropertiesNotifier = _read(userPropertiesNotifierProvider.notifier);

    // Start listening to both notifiers
    _userProfileDetailsNotifier.addListener(_onProfileDetailsStateChanged);
    _userPropertiesNotifier.addListener(_onUserPropertiesStateChanged);
  }

  void _onProfileDetailsStateChanged() {
    final userProfileDetailsState = _userProfileDetailsNotifier.state;
    final userPropertiesState = _userPropertiesNotifier.state;

    // Handle the combination of states
    if (userProfileDetailsState is UserProfileDetailsState.loading() ||
        userPropertiesState is UserPropertiesState.loading()) {
      state = const CombinedStates.loading();
    } else if (userProfileDetailsState is UserProfileDetailsState.error ||
        userPropertiesState is UserPropertiesState.error) {
      final error = userProfileDetailsState is UserProfileDetailsState.error
          ? userProfileDetailsState.error
          : userPropertiesState.error;
      state = CombinedStates.error(error);
    } else if (userProfileDetailsState is UserProfileDetailsState.data &&
        userPropertiesState is UserPropertiesState.data) {
      state = CombinedStates.success(
        profileEntity: userProfileDetailsState.profileEntity,
        userPropertiesEntity: userPropertiesState.userPropertiesEntity,
      );
    }
  }

  void _onUserPropertiesStateChanged() {
    // Call the same handler as profile details state changed
    _onProfileDetailsStateChanged();
  }

  @override
  void dispose() {
    // Stop listening to notifiers when disposing
    _userProfileDetailsNotifier.removeListener(_onProfileDetailsStateChanged);
    _userPropertiesNotifier.removeListener(_onUserPropertiesStateChanged);
    super.dispose();
  }
}

最后,你可以使用<<<> > ><> > ><> > 查询贵国统一名称:

final combinedNotifier = useProvider(combinedNotifierProvider);

Widget build(BuildContext context) {




相关问题
热门标签