gpt4 book ai didi

Flutter StreamProvider 使用了一个 `BuildContext`,它是提供者的祖先

转载 作者:行者123 更新时间:2023-12-04 09:13:04 27 4
gpt4 key购买 nike

我正在 Flutter 中开发一个应用程序(我还是个新手),但遇到以下错误:

Error: Could not find the correct Provider<List<Category>> above this Exercises Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- The provider you are trying to read is in a different route.

Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.

- You used a `BuildContext` that is an ancestor of the provider you are trying to read.

Make sure that Exercises is under your MultiProvider/Provider<List<Category>>.
This usually happen when you are creating a provider and trying to read it immediately.

For example, instead of:

```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```

consider using `builder` like so:

```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
我一直在网上查看,这显然与我在 execution_add.dart 中调用 Provider.of >(context) 时无法获得正确的“上下文”有关,我真的不明白为什么。因为正如您在我的 executions.dart 中看到的,我有“body:ExciseList()”,在其中我可以从 StreamProvider 获取类别,但是当我尝试通过单击我的“floatingActionButton”然后尝试访问它时打开我的 ExerciseAdd() 页面,它会引发该错误。
我真的很感激关于如何修复我的代码以及它为什么不起作用的解决方案(+ 解释)。
练习.dart
  Widget build(BuildContext context) {
return _isLoading
? Loading()
: MultiProvider(
providers: [
StreamProvider<List<Exercise>>(
create: (context) => DatabaseService().exercises,
),
StreamProvider<List<Category>>(
create: (context) => DatabaseService().categories,
),
ChangeNotifierProvider<ExerciseFilter>(
create: (context) => ExerciseFilter(isActive: true),
)
],
child: Scaffold(
appBar: AppBar(
title: Text('Exercises'),
elevation: 0.0,
actions: _buildActions(),
),
body: ExerciseList(),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.black,
child: Icon(Icons.add, color: Colors.white),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ExercisesAdd(),
),
);
},
),
),
);
}
}
练习_add.dart
 @override
Widget build(BuildContext context) {
final cats = Provider.of<List<Category>>(context);
print(cats.length);

return Scaffold(
appBar: AppBar(
title: Text('Add Exercise'),
elevation: 0.0,
),
body: SingleChildScrollView(
child: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 50.0),
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
SizedBox(height: 20.0),
TextFormField(
decoration:
textInputDecoration.copyWith(hintText: 'Exercise Name'),
validator: (value) {
if (value.isEmpty) {
return 'Exercise name is required';
}

return null;
},
onChanged: (value) {
setState(() {
exerciseName = value;
});
},
),
SizedBox(height: 20.0),
Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.white),
child: DropdownButtonFormField<String>(
decoration: dropdownDecoration,
value: exerciseCategory,
onChanged: (value) {
setState(() {
exerciseCategory = value;
});
},
items: categories.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value.name,
child: Text(value.name),
);
}).toList(),
),
),
SizedBox(height: 20.0),
RaisedButton(
elevation: 0,
color: Colors.black,
child: Text(
'Add Exercise',
style: TextStyle(color: Colors.white),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
bool failed = false;
String uid = await _auth.getCurrentUser();

if (uid != null) {
dynamic result = DatabaseService(uid: uid)
.addExercise(exerciseName, exerciseCategory);
if (result != null) {
Navigator.pop(context);
} else {
failed = true;
}
} else {
failed = true;
}

if (failed) {
setState(() {
error = 'Failed to add exercise. Please try again';
});
}
}
},
),
SizedBox(height: 12.0),
Text(
error,
style: TextStyle(color: Colors.red, fontSize: 14.0),
),
],
),
),
),
),
);
数据库服务().练习
List<Category> _categoryListFromSnapshot(QuerySnapshot snapshot) {
return snapshot.documents.map((doc) {
return Category(name: doc.data['category'] ?? '');
}).toList();
}

Stream<List<Category>> get categories {
return categoryCollection
.orderBy('category')
.snapshots()
.map(_categoryListFromSnapshot);
}
注意:StreamProvider 和 MultiProvider 等都是 'provider' 包的一部分(我使用最新版本)

最佳答案

您收到的错误描述了您当前所处的场景。

- The provider you are trying to read is in a different route.

Providers are "scoped". So if you insert of provider inside a route,then other routes will not be able to access that provider.


您正在导航到不同的路线并尝试访问提供程序,但它不再位于小部件树中。
您只需移动您的 MultiProvider在您在小部件树中使用的任何导航器上方。您可能正在使用 MaterialApp为此,请移步 MultiProvider并制作 MaterialApp它是 child .

关于Flutter StreamProvider 使用了一个 `BuildContext`,它是提供者的祖先,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63315716/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com