无法快速访问提供程序

问题描述 投票:0回答:2

我有一个简单的提供程序类:-

class DataProvider with ChangeNotifier {
   int count;
   void updateCount() {
     count = count + 1;
     notifyListeners();
   }
}

我正在将此提供程序附加到以下课程:-

class MyWidget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => DataProvider(),
      child: Scaffold(
        body: raisedButton(
          onPressed: () {
            Provider.of<DataProvider>(context).updateCount();
          }
           child: Text("Click!")
         ),
       ),
     ),
   }

及其给我以下错误:-

 I/flutter (32011): Error: Could not find the correct Provider<DataProvider> above this MyWidget 
 Widget
 I/flutter (32011): To fix, please:
 I/flutter (32011):   * Ensure the Provider<DataProvider> is an ancestor to this MyWidget Widget
 I/flutter (32011):   * Provide types to Provider<DataProvider>
 I/flutter (32011):   * Provide types to Consumer<DataProvider>
 I/flutter (32011):   * Provide types to Provider.of<DataProvider>()
 I/flutter (32011):   * Ensure the correct `context` is being used. 

这可能是什么原因?

编辑:-当我从定义的窗口小部件的任何子窗口小部件访问提供程序时,它工作正常。 ChangeNotifierProvider

flutter provider
2个回答
0
投票

您需要将raisedButton包装在Consumer中。

Consumer小部件有两个主要用途:

它允许我们在没有供应商的情况下从提供商那里获取价值BuildContext是所述提供程序的后代,因此无法使用Provider.of。这种情况通常发生在创建提供程序的小部件也是其消费者之一,例如以下示例:

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => Foo(),
    child: Text(Provider.of<Foo>(context).value),
  );
}

此示例将抛出ProviderNotFoundException,因为使用BuildContext调用Provider.of,该BuildContext是提供者。

相反,我们可以使用Consumer小部件,它将调用Provider.of拥有自己的BuildContext。

使用消费者,上一个示例将成为:

@override
Widget build(BuildContext context) {
  return ChangeNotifierProvider(
    create: (_) => Foo(),
    child: Consumer<Foo>(
      builder: (_, foo, __) => Text(foo.value),
    },
  );
}

这不会引发ProviderNotFoundException,并且会正确构建文本。每当值foo更改时,它还将更新Text。

参见:https://pub.dev/documentation/provider/latest/provider/Consumer-class.html


0
投票

这是因为您使用错误的Provider.of<DataProvider>(context).updateCount()来调用context。您正在使用context方法提供的build,该方法在层次结构中比您尝试访问的提供者要高。您需要使用属于提供者的后代(在层次结构中较低)的context

Scaffold包装在Builder小部件中,这会在小部件层次结构中的该级别上显示一个新的context,并改用该上下文。

您也可以使用Consumer,尽管在您的示例中它不是最佳的,因为每次在Provider中调用Consumer时,notifyListeners()都会重建,这将是多余的,因为您的UI不会更改。

© www.soinside.com 2019 - 2024. All rights reserved.