flutter 为什么不能使用非静态后期提供程序?

cfh9epnr  于 2023-06-30  发布在  Flutter
关注(0)|答案(1)|浏览(127)

bounty将在23小时内到期。此问题的答案有资格获得+50声望奖励。Ruble正在寻找一个答案从一个有信誉的来源

我们可以这样做:

class WorldModel {
  WorldModel({required this.skyModel});

  final SkyModel skyModel;

  static final instance = Provider<WorldModel>(
    (ref) => WorldModel(
      skyModel: SkyModel(),
    ),
  );

  final countBirds = Provider<int>((ref) => 25);
}

这意味着我们只能在访问WorldModel示例之后才能访问countBirds提供程序。那些(在build()方法中):

Widget build(BuildContext context, WidgetRef ref) {
  final worldModel = ref.watch(WorldModel.instance);
  final countBirds = ref.watch(worldModel.countBirds);
  return Text(countBirds.toString());
}

否则,我们甚至可以这样定义它:

late final countBirds = Provider<int>((ref) => 5);

它工作得很好,并执行其功能100%。即使在使用.autoDispose修改器时,一切都工作正常,并被丢弃。* 但是,官方文档强烈建议仅将提供程序用作最终提供程序
提供者应该始终是最终的。
这是否意味着它们可以是late为什么和什么是陷阱?
关于
*function**
为什么我需要这个(我说的是WorldModel类中的定义)?这是因为countBirds可能依赖于WorldModel类的某些字段。我不能用任何其他方式来做,只是因为我认为这是 * 依赖注入的好实践 *。下面是一个很好的例子:

class WorldModel {
  WorldModel({required this.skyModel});

  final SkyModel skyModel;

  static final instance = Provider<WorldModel>(
    (ref) => WorldModel(skyModel: SkyModel()),
  );

  late final countBirds = Provider<int>((ref) => skyModel.countBirds);
}

class SkyModel {
  late int countBirds;
}
wkftcu5l

wkftcu5l1#

不建议使用提供程序作为static,虽然我不认为这在技术上有问题,但这仍然是一个不好的做法。
至于在没有static关键字的类中将提供程序定义为final,这将导致为类的每个示例创建一个新的提供程序,因此当您失去对类示例的访问权限时,您将无法访问提供程序,如果提供程序不是自动可丢弃的,这将是一个更大的问题。
提供程序可以按以下方式定义

final myProvider = Provider<WorldModel>((ref) {
  throw UnimplementedError();
});

final countBirds = Provider<int>((ref) {
  throw UnimplementedError();
});

然后,您可以在访问小部件树之前初始化提供程序,方法是使用ProviderScope扭曲父小部件

ProviderScope(
  overrides: [
    myProvider.overrideWithValue(skyModel),
    countBirds.overrideWithValue(skyModel.countBirds),
  ],
  child: const MyWidget(),
)

然后,您可以访问ProviderScope下的小部件树中的任何小部件中的提供程序。
你可以做的另一件事是使用.family修饰符

final myProvider = Provider.family<WorldModel, SkyModel>((ref, skyModel) {
  return WorldModel(skyModel: skyModel);
});

但是,您必须传递相同的SkyModel示例以重用相同的提供程序示例,否则您将得到一个新的提供程序

相关问题