【发布时间】:2021-06-30 11:38:54
【问题描述】:
说明
我有一个页面(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 行可以调用我的另一个通知程序。我在代码中将这些行标记为 cmets
class InitialElementResultNotifier with ChangeNotifier{
// External Notifier
// ---------------------------------------------------------------------------
LoaderNotifier _loaderNotifier; // => New line !
// Variables
// ---------------------------------------------------------------------------
FormInitialElementModel dataReceived;
Future myFuture;
// Constructor
// ---------------------------------------------------------------------------
InitialElementResultNotifier({
@required String getData,
LoaderNotifier loaderNotifier, // => 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:
【问题讨论】:
-
我不明白提到使用ChangeNotifierProvider而不是Provider,我这样做了!