1

我正在尝试拥有一个基本的 Freezed 接口,我的应用程序实体接口可以扩展它,以便我可以在接口上调用冻结的函数。我已经在这里开始了这个过程,到目前为止它似乎正在工作:

abstract class IUserRegistrationEntity<T> extends FreezedClass<T> {
  String get nickName;
  String get email;
  String get confirmEmail;
  String get password;
  String get confirmPassword;
}

abstract class FreezedClass<T> {
  T get copyWith;
  Map<String, dynamic> toJson();
}

冻结类:

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:vepo/domain/user_registration/i_user_registration_entity.dart';

part 'user_registration_entity.freezed.dart';
part 'user_registration_entity.g.dart';

@freezed
abstract class UserRegistrationEntity with _$UserRegistrationEntity {
  @Implements.fromString(
      'IUserRegistrationEntity<\$UserRegistrationEntityCopyWith<IUserRegistrationEntity>>')
  const factory UserRegistrationEntity(
      {String nickName,
      String email,
      String confirmEmail,
      String password,
      String confirmPassword}) = _IUserRegistrationEntity;

  factory UserRegistrationEntity.fromJson(Map<String, dynamic> json) =>
      _$UserRegistrationEntityFromJson(json);
}

但是现在我需要将 fromJson 工厂构造函数添加到接口中。我认为可能是我正在寻找的东西,尽管我真的不知道如何在我的代码中实现它:

 T deserialize<T extends JsonSerializable>(
    String json,
    T factory(Map<String, dynamic> data),
  ) {
    return factory(jsonDecode(json) as Map<String, dynamic>);
  }
You an then call it with:

var myValue = deserialize(jsonString, (x) => MyClass.fromJson(x));

将 fromJson 添加到我的冻结界面的任何帮助将不胜感激。

4

2 回答 2

2

我找到了一种方法来获得与冻结对象的接口或“抽象”编程相同的好处,同时仍然可以调用那些冻结的函数:

@freezed
abstract class Person with _$Person {
  @With(BasicPersonMixin)
  const factory Person.basicPerson(
      {int? id, String? firstName, String? lastName}) = BasicPerson;

  @With(FancyPersonMixin)
  const factory Person.fancyPerson({String? firstName, required String extraPropMiddleName, String? lastName}) =
      FancyPerson;

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  const Person._();

  void functionThatEveryPersonShares() {
    print('I am a person');
  }

  String greet() {
    return 'override me with a mixin or abstract class';
  }
}

mixin FancyPersonMixin {

  String get extraPropMiddleName {
      return 'my default middle name is John`;
  }

  String greet() {
    return 'Salutations!';
  }

  void specialisedFunctionThatOnlyIHave() {
    print('My middle name is $extraPropMiddleName');
  }
}

mixin BasicPersonMixin {
  String greet() {
    return 'Hi.';
  }
}

现在我们有 2 个具体的类:BasicPersonFancyPerson它们都是 a Person。现在我们可以对Person整个应用程序进行编程,并且仍然可以调用.copyWith等等.fromJson。不同类型的Person可以通过使用 mixins 彼此独立地变化,并且仍然可以用作Person类型。适用于泛型等(来自 docs - @With.fromString('AdministrativeArea<House>')),但我为这个问题保持了简单的示例,以最简单地展示好处。您还可以让 Person 扩展另一个基类。

于 2021-07-03T02:43:34.583 回答
0

我找到了另一种让你比我的其他答案更抽象的方法。假设您在一个高度抽象的超类中,因此您不想使用像Person. 您想使用“基础冻结对象”;只需在括号中将您的类型转换为动态,然后继续并copyWith自由使用。当然,它不是类型安全的,但如果它允许您在超类中而不是在每个子类中做某事,那么它是一个有价值的选择。

mixin LocalSaveMixin<TEntity extends LocalSaveMixin<TEntity>> on Entity {
  LocalRepository<TEntity> get $repository;
  Ref? get provider;

  TEntity $localFetch() {
    return ($repository.$localFetch() as dynamic).copyWith(provider: provider)
        as TEntity;
  }

  TEntity $localSave() {
    return $repository.$localSave(entity: this as TEntity);
  }
}
于 2021-12-30T19:46:10.133 回答