如何在 Flutter 中正确扩展自定义 Provider

How to correctly extend a custom Provider in Flutter

我有一个父级 ChangeNotifier ParentProvider,另外 2 个提供商扩展了 ParentProvider

ChildProviderA, ChildProviderB.

我有一条路线叫做 MyScreen

class MyScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    if(ModalRoute.of(context).settings.arguments != null){
      return ChangeNotifierProvider(
        create: (context) => ChildProviderA(),
        child: _Screen()
      );
    }
    return ChangeNotifierProvider(
      create: (context) => ChildProviderB(),
      child: _Screen()
    );
  }
}

根据我想使用提供程序的参数,在任何一种情况下,我都想在 _Screen 小部件的 ParentProvider 中调用一个名为 initData() 的函数。

@override
  Widget build(BuildContext context) {
...
    Provider.of<ParentProvider>(context, listen: false).initData();
...
}

这给我一个错误

Error: Could not find the correct Provider<ParentProvider> above this _Screen Widget

如果我用Provider.of<ChildProviderA>(context, listen: false).initData();

Provider.of<ChildProviderB>(context, listen: false).initData(); 它有效,但我希望在使用的任何一个子 Provider 中都能调用 initData。

如何做到这一点?

Provider.of 查找具有完全给定类型的提供者。它不包括子类型。

如果子屏幕需要访问一些具有相同格式的不同数据,您可以在两种情况下使用相同的提供程序,通过构造函数将不同的数据传递给它:

class MyScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (condition) {
      return ChangeNotifierProvider(
        create: (context) => ParentProvider(data1),
        child: _Screen(),
      );
    }
    return ChangeNotifierProvider(
      create: (context) => ParentProvider(data2),
      child: _Screen(),
    );
  }
}

如果您确实有两个不同的 ChangeNotifier 实现共享同一接口,您可以使用父类型提供和访问它们:

class MyScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    if (condition) {
      return ChangeNotifierProvider<ParentProvider>(
        create: (context) => ChildProviderA(),
        child: _Screen(),
      );
    }
    return ChangeNotifierProvider<ParentProvider>(
      create: (context) => ChildProviderB(),
      child: _Screen(),
    );
  }
}

定义 children 提供程序时,请使用扩展。 此外,所有提供者都必须在 children 之上,并且在他们正在收听的同一路线中。您可以在定义 children 类 时尝试添加 extends ParentProvider。即

class ChildA  extends ParentProvider {

//here you have access to methods in parent.
you can add a method here that triggers something form the parent.

void childMethod ()=> methodFromParentLikeInitData();

}