flutter Riverpod 2.0发电机与清洁建筑

kiayqfof  于 2023-02-13  发布在  Flutter
关注(0)|答案(1)|浏览(109)

我正在尝试使用带有生成器和清洁架构的riverpod 2. 0状态管理。我的目标很简单:我调用API从服务器获取文档,如果失败,我从资产获取文件。我已经成功地设置了数据(数据源、模型和repo impl.)和域(实体、repo、用例)层。现在我正在处理表示层,但我确信我做错了什么。
特别是,我不认为以这种方式初始化数据源和repo impl.是完全正确的。但主要的问题是,在数据状态的页面上,我没有收到实体。我已经尝试更改通知程序的返回类型,但我只能获得状态,而不是实体。
有什么建议吗?
使用案例:

import 'package:example/features/app_language/domain/repositories/available_languages_repository.dart';
import 'package:example/features/app_language/presentation/riverpod/available_languages_state.dart';

class AvailableLanguagesUseCase {
 final AvailableLanguagesRepository availableLanguagesRepository;

 AvailableLanguagesUseCase({required this.availableLanguagesRepository});

 Future<AvailableLanguagesState> getAvailableLanguages() async {
   final availableLanguages =
       await availableLanguagesRepository.getAvailableLanguages();
   return availableLanguages
       .fold((error) => const AvailableLanguagesState.error(),
           (availableLanguagesEntity) {
     print(availableLanguagesEntity);
     return AvailableLanguagesState.data(
         availableLanguagesEntity: availableLanguagesEntity);
   });
 }
}

国家:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:example/features/app_language/domain/entities/available_languages_entity.dart';

part 'available_languages_state.freezed.dart';

@freezed
abstract class AvailableLanguagesState with _$AvailableLanguagesState {
  ///Loading
  const factory AvailableLanguagesState.loading() =
      _AvailableLanguagesStateLoading;

  ///Data
  const factory AvailableLanguagesState.data(
          {required AvailableLanguagesEntity availableLanguagesEntity}) =
      _AvailableLanguagesStateData;

  ///Error
  const factory AvailableLanguagesState.error([String? error]) =
      _AvailableLanguagesStateError;
}

异步通告程序:

import 'package:http/http.dart' as http;
import 'package:example/features/app_language/data/datasources/available_languages_local_data_source.dart';
import 'package:example/features/app_language/data/datasources/available_languages_remote_data_source.dart';
import 'package:example/features/app_language/data/repositories/available_languages_repository_impl.dart';
import 'package:example/features/app_language/domain/usecase/available_languages_use_case.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'available_languages_notifier.g.dart';

@riverpod
class AvailableLanguagesAsyncNotifier
    extends _$AvailableLanguagesAsyncNotifier {
  @override
  Future<void> build() async {
    return getAvailableLanguages();
  }

  Future<void> getAvailableLanguages() async {
    final AvailableLanguagesLocalDataSourceImpl
        availableLanguagesLocalDataSourceImpl =
        AvailableLanguagesLocalDataSourceImpl();
    final AvailableLanguagesRemoteDataSourceImpl
        availableLanguagesRemoteDataSourceImpl =
        AvailableLanguagesRemoteDataSourceImpl(client: http.Client());

    final AvailableLanguagesUseCase availableLanguagesUseCase =
        AvailableLanguagesUseCase(
            availableLanguagesRepository: AvailableLanguagesRepositoryImpl(
                availableLanguagesLocalDataSource:
                    availableLanguagesLocalDataSourceImpl,
                availableLanguagesRemoteDataSource:
                    availableLanguagesRemoteDataSourceImpl));

    state = const AsyncValue.loading();
    //TODO DELETE DELAY
    await Future.delayed(const Duration(seconds: 2));
    state = AsyncValue.data(
        await availableLanguagesUseCase.getAvailableLanguages());
  }
}

页码:

class InitialSetupPage extends StatelessWidget {
 const InitialSetupPage({super.key});

 @override
 Widget build(BuildContext context) {
   return Consumer(
     builder: (context, ref, child) {
       final a = ref.watch(availableLanguagesAsyncNotifierProvider);
       print("state: $a");
       return a.maybeWhen(
         loading: () => Container(
           color: Colors.purple,
         ),
         data: (availableLanguagesEntity) =>
             Container(color: Colors.green, child: Center()),
         error: (error, stackTrace) => Container(
           color: Colors.red,
         ),
         orElse: () => Container(
           color: Colors.lightBlue,
         ),
       );
     },
   );
 }
}

先谢了
编辑:
只是为了补充我已经尝试过但没有说服我的细节:
通知人:

import 'package:http/http.dart' as http;
import 'package:example/features/app_language/data/datasources/available_languages_local_data_source.dart';
import 'package:example/features/app_language/data/datasources/available_languages_remote_data_source.dart';
import 'package:example/features/app_language/data/repositories/available_languages_repository_impl.dart';
import 'package:example/features/app_language/domain/usecase/available_languages_use_case.dart';
import 'package:example/features/app_language/presentation/riverpod/available_languages_state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'available_languages_notifier.g.dart';

@riverpod
class AvailableLanguagesAsyncNotifier
    extends _$AvailableLanguagesAsyncNotifier {
  @override
  Future<AvailableLanguagesState> build() async {
    getAvailableLanguages();
    return const AvailableLanguagesState.loading();
  }

  getAvailableLanguages() async {
    final AvailableLanguagesLocalDataSourceImpl
        availableLanguagesLocalDataSourceImpl =
        AvailableLanguagesLocalDataSourceImpl();
    final AvailableLanguagesRemoteDataSourceImpl
        availableLanguagesRemoteDataSourceImpl =
        AvailableLanguagesRemoteDataSourceImpl(client: http.Client());

    final AvailableLanguagesUseCase availableLanguagesUseCase =
        AvailableLanguagesUseCase(
            availableLanguagesRepository: AvailableLanguagesRepositoryImpl(
                availableLanguagesLocalDataSource:
                    availableLanguagesLocalDataSourceImpl,
                availableLanguagesRemoteDataSource:
                    availableLanguagesRemoteDataSourceImpl));

    state = const AsyncValue.loading();
    //TODO DELETE DELAY
    await Future.delayed(const Duration(seconds: 2));
    state = AsyncValue.data(
        await availableLanguagesUseCase.getAvailableLanguages());
  }
}

页码:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:example/features/app_language/presentation/riverpod/available_languages_notifier.dart';

class InitialSetupPage extends StatelessWidget {
  const InitialSetupPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, ref, child) {
        final a = ref.watch(availableLanguagesAsyncNotifierProvider);
        print("state: $a");
        return a.maybeWhen(
          loading: () => Container(
            color: Colors.purple,
          ),
          data: (availableLanguagesEntity) => Container(
              color: Colors.green,
              child: Center(
                child: Text(availableLanguagesEntity.maybeWhen(
                    data: (availableLanguagesEntity) =>
                        availableLanguagesEntity.availableLanguagesEntity.first,
                    orElse: () {
                      return " ";
                    })),
              )),
          error: (error, stackTrace) => Container(
            color: Colors.red,
          ),
          orElse: () => Container(
            color: Colors.lightBlue,
          ),
        );
      },
    );
  }
}
jgovgodb

jgovgodb1#

找到了一个解决方案。主要问题是用例类。
现在,它返回Future,而不是AvailableLanguagesState

import 'package:dartz/dartz.dart';
import 'package:example/core/errors/failures.dart';
import 'package:example/features/app_language/domain/entities/available_languages_entity.dart';
import 'package:example/features/app_language/domain/repositories/available_languages_repository.dart';

class AvailableLanguagesUseCase {
  final AvailableLanguagesRepository availableLanguagesRepository;

  AvailableLanguagesUseCase({required this.availableLanguagesRepository});

  Future<Either<Failure, AvailableLanguagesEntity>>
      getAvailableLanguages() async {
    return await availableLanguagesRepository.getAvailableLanguages();
  }
}

这是通告程序

import 'package:http/http.dart' as http;
import 'package:example/features/app_language/data/datasources/available_languages_local_data_source.dart';
import 'package:example/features/app_language/data/datasources/available_languages_remote_data_source.dart';
import 'package:example/features/app_language/data/repositories/available_languages_repository_impl.dart';
import 'package:example/features/app_language/domain/usecase/available_languages_use_case.dart';
import 'package:example/features/app_language/presentation/riverpod/available_languages_state.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'available_languages_notifier.g.dart';

@riverpod
class AvailableLanguagesNotifier extends _$AvailableLanguagesNotifier {
  @override
  AvailableLanguagesState build() {
    getAvailableLanguages();
    return const AvailableLanguagesState.loading();
  }

  void getAvailableLanguages() async {
    final AvailableLanguagesLocalDataSourceImpl
        availableLanguagesLocalDataSourceImpl =
        AvailableLanguagesLocalDataSourceImpl();
    final AvailableLanguagesRemoteDataSourceImpl
        availableLanguagesRemoteDataSourceImpl =
        AvailableLanguagesRemoteDataSourceImpl(client: http.Client());

    final AvailableLanguagesUseCase availableLanguagesUseCase =
        AvailableLanguagesUseCase(
            availableLanguagesRepository: AvailableLanguagesRepositoryImpl(
                availableLanguagesLocalDataSource:
                    availableLanguagesLocalDataSourceImpl,
                availableLanguagesRemoteDataSource:
                    availableLanguagesRemoteDataSourceImpl));

    //TODO DELETE DELAY
    await Future.delayed(const Duration(seconds: 2));

    final failureOrAvailableLanguagesEntity = await availableLanguagesUseCase.getAvailableLanguages();

    failureOrAvailableLanguagesEntity .fold(
        (error) => state = const AvailableLanguagesState.error(),
        (availableLanguagesEntity) async => state =
            AvailableLanguagesState.data(
                availableLanguagesEntity: availableLanguagesEntity));
  }
}

页码:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:example/features/app_language/presentation/riverpod/available_languages_notifier.dart';

class InitialSetupPage extends StatelessWidget {
  const InitialSetupPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (context, ref, child) {
        final a = ref.watch(availableLanguagesNotifierProvider);

        print("state: $a");
        return a.maybeWhen(
          loading: () => Container(
            color: Colors.purple,
          ),
          data: (state) => Container(
              color: Colors.green,
              child: Center(
                child: Text(state.availableLanguagesEntity.first),
              )),
          error: (_) => Container(
            color: Colors.red,
          ),
          orElse: () => Container(
            color: Colors.lightBlue,
          ),
        );
      },
    );
  }
}

对AvailableLanguagesNotifier的质量仍有一些疑问

相关问题