我在一个小部件中有两个对makeChild(...)
的调用。在树的顶部有一个ChangeNotifierProvider
,在makeChild
函数中,我通过Provider.of<...>(context)
访问数据模型。
showModalBottomSheet
的调用)中,它抛出一个错误,说the correct provider couldn't be found above this widget
.
import 'package:flutter/material.dart';
class PuzzleBox extends StatelessWidget {
const PuzzleBox({
Key? key,
required this.makeChild,
}) : super(key: key);
final Function makeChild;
@override
Widget build(BuildContext context) {
return Expanded(
child: GestureDetector(
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) =>
// THIS DOESN'T HAVE THE RIGHT CONTEXT (PROVIDER NOT FOUND)
makeChild(showUI: true),
);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
const Divider(height: 24),
Center(
child: IgnorePointer(
// THIS RENDERS FINE AND HAS THE CORRECT CONTEXT
child: FittedBox(child: makeChild(showUI: false)))),
],
),
),
);
}
}
换句话说,直接在小部件树中的函数生成了一个可以访问我的Provider的小部件,但是在showModalBottomSheet
中的相同函数生成了一个不能访问的小部件。为什么?
为了避免代码复杂化和传递参数,您可以使用mobx包:
https://pub.dev/packages/mobx
https://pub.dev/packages/flutter_mobx
https://pub.dev/packages/mobx_codegen
它不需要上下文,所以这将大大简化你的代码,并允许你从任何地方访问提供者。
所有你要做的就是创建您的provider类使用正确的注释:@observable
,@computed
@action
并使用build_runner生成dart文件的一部分,您将在文档中看到。
在此之后,你必须全局声明你的提供者,并导入它以在你需要的地方使用它。
final myProvider = MyClassProvider();
// Anywhereby importing the file where is myProvider
myProvider.value = 'x';