如何解决Flutter 使用 ProxyProvider 说明有效的代码不起作用的代码错误
说明
我有一个页面 (InitialElementResultScreen),它必须等待 InitialElementResultNotifier 中的几个操作完成才能显示页面的其余部分。
有效的代码
我的 InitialElementResultScreen:
class InitialElementResultScreen extends StatelessWidget {
final String title;
InitialElementResultScreen({
Key key,@required this.title,}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarWidget.withoutMenu(title: title),body: _buildBody(context),);
}
Widget _buildBody(BuildContext context){
// => For use variable in my screen I use the notifier.
var _initialElementResultProvider = Provider.of<InitialElementResultNotifier>(context);
return SingleChildScrollView(
child: Column(
children: [
ContainerComponent(
colorContainer: AppColors.backgroundLightBasic,children: [
FutureBuilder(
future: _initialElementResultProvider.myFuture,builder: (context,snapshot){
if(!snapshot.hasData) {
return Text('loading');
}else{
return Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
// ... some widgets
],);
}
}
)
],),],);
}
}
当我调用我的 InitialElementResultScreen 时:
ChangeNotifierProvider<InitialElementResultNotifier>(
create: (BuildContext context) => InitialElementResultNotifier(getData: data)
)
我的 InitialElementResultNotifier 直接在其构造函数中接收外部数据。它将它们转换为对象,以便我可以对它们进行操作。
我的 InitialElementResultNotifier :
class InitialElementResultNotifier with ChangeNotifier{
// External Notifier
// ---------------------------------------------------------------------------
// Variables
// ---------------------------------------------------------------------------
FormInitialElementModel dataReceived;
Future myFuture;
// Constructor
// ---------------------------------------------------------------------------
InitialElementResultNotifier({
@required String getData,}){
_initialise(getData);
}
// Initialisation
// ---------------------------------------------------------------------------
Future _initialise(String getData) async{
print('--- initialise');
dataReceived = await _convertDataReceived(getData);
myFuture = loadingInitialElementData();
}
// Functions public
// ---------------------------------------------------------------------------
Future<void> loadingInitialElementData() async
{
print('---------------------- dataReceived');
print(dataReceived); // => I see my data in the console
// ... some operations
}
}
不起作用的代码
在我的loadingInitialElementData()函数中,我想访问另一个通知程序。通知程序 LoaderNotifier 根据其状态管理不同消息的显示,我将根据我在 loadingInitialElementData() 函数中的操作更改这些状态。
为此,我将使用代理提供程序。所以现在我这样称呼我的 InitialElementResultScreen:
ChangeNotifierProvider<LoaderNotifier>(
create: (BuildContext context) => LoaderNotifier()
),ProxyProvider<LoaderNotifier,InitialElementResultNotifier>(
update: (BuildContext context,LoaderNotifier loaderNotifier,InitialElementResultNotifier initialElementResultNotifier) {
return InitialElementResultNotifier(
getData: data,loaderNotifier: loaderNotifier
);
}
),
我将更新我的InitialElementResultNotifier:
除了 3 行可以调用我的其他通知程序之外,所有代码都相同。我在代码中将这些行标记为注释
class InitialElementResultNotifier with ChangeNotifier{
// External Notifier
// ---------------------------------------------------------------------------
LoaderNotifier _loaderNotifier; // => New line !
// Variables
// ---------------------------------------------------------------------------
FormInitialElementModel dataReceived;
Future myFuture;
// Constructor
// ---------------------------------------------------------------------------
InitialElementResultNotifier({
@required String getData,// => New line !
}){
_loaderNotifier = loaderNotifier; // => New line !
_initialise(getData);
}
// Initialisation
// ---------------------------------------------------------------------------
Future _initialise(String getData) async{
print('--- initialise');
dataReceived = await _convertDataReceived(getData);
myFuture = loadingInitialElementData();
}
// Functions public
// ---------------------------------------------------------------------------
Future<void> loadingInitialElementData() async
{
print('---------------------- dataReceived');
print(dataReceived); // => I see my data in the console
// ... some operations
}
}
错误
我不明白为什么会出现这个错误,我的错误是什么?
======== Exception caught by widgets library =======================================================
The following assertion was thrown building InitialElementResultScreen(dirty,dependencies: [_InheritedProviderScope<InitialElementResultNotifier>]):
Tried to use Provider with a subtype of Listenable/Stream (InitialElementResultNotifier).
This is likely a mistake,as Provider will not automatically update dependents
when InitialElementResultNotifier is updated. Instead,consider changing Provider for more specific
implementation that handles the update mechanism,such as:
- ListenableProvider
- ChangeNotifierProvider
- ValueListenableProvider
- StreamProvider
Alternatively,if you are making your own provider,consider using InheritedProvider.
If you think that this is not an error,you can disable this check by setting
Provider.debugCheckInvalidValueType to `null` in your main file:
解决方法
我很想帮助你,但我觉得我很难跟上。然而,我注意到可能有帮助的一件事是,在 InitialElementResultNotifier
myFuture
中声明,但未初始化,并且在该类中没有您在 notifyListeners
中调用 InitialElementResultScreen
因此在 build
{当 dataReceived
和 myFuture
最终收到值或更改时,不会调用 {1}}。但是将 FutureBuilder
与 Provider
结合使用的整个想法对我来说是非常错误的。如果您要继续进行此特定设计,则需要研究 Completers,但我建议您不要这样做。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。