我对 Flutter Provider 模式有疑问。用户重定向到新屏幕后,找不到提供程序。
按照我之前的问题(在此小部件上方找不到正确的提供者),我编写了以下代码:
class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = 'Tap to select';
return MaterialApp(
title: title,
home: Scaffold(
appBar: AppBar(
title: Text(title),
),
body: NewRouteBody()
));
}
}
class NewRouteBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
var user = Provider.of<UserRepository>(context);
return ListView(...)
Run Code Online (Sandbox Code Playgroud)
我做了同样的事情,但我再次收到错误消息,指出它无法在此小部件 ( NewRouteBody)上方找到正确的提供程序。
试图以某种方式修复它,在谷歌上搜索了几个小时的答案但没有成功......
任何帮助表示赞赏。
编辑
这是UserRepository其中包含模式:
class UserRepository with ChangeNotifier {
User user;
Status _status = Status.Uninitialized;
Status get status => …Run Code Online (Sandbox Code Playgroud) 我正在使用Provider. 我有两个类:class TenderApiData {}它是独立类(不是小部件)。我怎么能写accesstoken来AppState?
class AppState extends ChangeNotifier // putted to ChangeNotifierProvider
{
String _accesstoken; // need to fill not from widget but from stand alone class
String _customer; // Fill from widget
List<String> _regions; // Fill from widget
List<String> _industry; // Fill from widget
...
}
Run Code Online (Sandbox Code Playgroud)
我需要accesstoken从独立类中读/写的方法。
或者我的应用程序架构有问题?
这是完整的源代码。
我正在使用提供程序进行状态管理。我的表单中有多种类型的字段。问题在于文本字段 每当我更改文本时,它的行为都很奇怪,就像输入的文本以相反的顺序显示一样。
class MyProvider with ChangeNotifier{
String _name;
String get name => _name;
setname(String name) {
_name = name;
notifyListeners();
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final MyProvider myProvider = Provider.of<MyProvider>(context);
final TextEditingController _nameController = TextEditingController(
text: myProvider.name,
);
return TextField(
controller: _nameController,
onChanged: myProvider.setname,
);
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 bloc 来处理注册表单的状态。但我收到错误:
Error: Could not find the correct Provider<CreateDidBloc> above this BlocBuilder<CreateDidBloc, CreateDidState> Widget。
正如您在错误中看到的,我确实使用了块CreateDidBloc和状态CreateDidState,并通过 BlocBuilder 获取它们。
BlocBuilder 位于我的“注册”页面中,在我的例子中称为Creation。当我从介绍页面导航到创建页面时,会发生该错误。
下面是我的摘录,其中我用和MaterialApp包装了创建页面,以便创建页面可以访问 Bloc 和存储库。但由于某种原因,导航到创建页面后,页面找不到 BlocProvider 。RepositoryProviderBlocProvidercreationCreateDidBloc
initialRoute: "/introduction",
routes: {
"/introduction": (context) => Introduction(),
"/create": (context) => RepositoryProvider(
create: (context) => CreateDidRepository(),
child: BlocProvider(
create: (BuildContext context) => CreateDidBloc(
repo: context.read<CreateDidRepository>(),
),
child: Creation(),
),
),
},
Run Code Online (Sandbox Code Playgroud)
这是我导航到屏幕的方式Creation:
Navigator.push(context,
PageTransition(type: PageTransitionType.fade, child: Creation()));
Run Code Online (Sandbox Code Playgroud)
创建(注册)页面:
@override
Widget …Run Code Online (Sandbox Code Playgroud) 我见过很多关于为什么一个小部件不必要地重建的问题,但我正在寻找一种方法来理解触发它们的原因。
所以我在视图小部件上放置了一个断点,我得到了一个相当大的堆栈(裁剪后的 - 它大了 5 倍):
我们应该如何追踪该死的重建起源?
// Are these the same?
final model = Provider.of<Model>(context, listen: false);
final model = context.read<Model>();
// Are these the same?
final model = Provider.of<Model>(context);
final model = context.watch<Model>();
Run Code Online (Sandbox Code Playgroud)
他们是一样的还是不一样的?如果是,那么为什么read在build()方法内部使用时会出现此错误,而Provider.of()有效?
试图
context.read<Model>在build方法或update提供者的回调中使用。
我socket_io_client在我的 flutter 应用程序中使用 v0.9.12 (仍然没有使用空安全)。当应用程序启动时,我正在与后端服务器创建套接字连接,并允许子小部件使用提供程序访问它。
我试图开始在构造函数中创建连接,以便当我需要使用套接字客户端时,它可能已经初始化了。
\n这是我的提供程序类,它创建了套接字连接:
\nclass SocketClient {\n SocketClient() {\n _initializer = initialize();\n }\n\n Future _initializer;\n\n /// Socket client\n Socket client;\n\n /// Wait until the client is properly connected with the server\n Future finishInitializing() => _initializer;\n\n /// Initialize the socket connection with the server\n Future initialize() async {\n final completer = Completer<Socket>();\n\n final socket = io(\n \'http://localhost:3000/gateway\',\n OptionBuilder() //\n .setTransports([\'websocket\'])\n .disableAutoConnect()\n .setQuery({\'token\': \'TOKEN\'})\n .build(),\n )..connect();\n\n socket\n ..onConnect((_) {\n completer.complete(socket);\n });\n\n client = await …Run Code Online (Sandbox Code Playgroud) 本周我开始在 flutter 中进行开发,但我无法解决这个问题。
\n\n我正在构建一个登录页面,该页面调用 API 进行登录,然后重定向到主页。\n这是第一个代码块中生成的异常。Navigator.pushReplacement\n此时apiCall.isFetching为 false,导致获取结束并apiCall.response包含所需的数据。
异常详细信息:
\n\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90 Exception caught by widgets library \xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\nThe following assertion was thrown building Consumer<ApiCallChangeNotifier>(dirty, dependencies: [InheritedProvider<ApiCallChangeNotifier>]):\nsetState() or markNeedsBuild() called during build.\n\nThis Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. …Run Code Online (Sandbox Code Playgroud) 我目前在获取Provider' value ininitstate`时遇到问题。
我想在 Appbar 和 body 中的其他部分的下拉列表中设置默认值。但我有一个错误说dependOnInheritedElement() was called before initstate() in flutter.
我的完整代码如下
main.dart
import 'package:test_eoil/model/button_data.dart';
import 'package:test_eoil/model/output_data.dart';
import 'screen/screen.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(providers: [
// ChangeNotifierProvider<ChordData>(create: (context) => ChordData()),
ChangeNotifierProvider<OutputData>(create: (context) => OutputData()),
ChangeNotifierProvider<ButtonData>(create: (context) => ButtonData())
],
child: MaterialApp(
home: Screen(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
screen.dart 在屏幕文件夹中
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_eoil/model/button_data.dart';
import 'package:test_eoil/model/output_data.dart'; …Run Code Online (Sandbox Code Playgroud) 在 Riverpod文档中,它说:
这
context.read(myProvider)就是解决方案的地方。使用它,我们可以将之前的代码重构为:
Run Code Online (Sandbox Code Playgroud)@override Widget build(BuildContext context) { return RaisedButton( onPressed: () => context.read(counterProvider).state++, child: Text('increment'), ); }通过这样做,点击我们的按钮仍然会增加计数器。但是我们不再听取提供者的意见,这避免了不必要的重建。
但后来它说:
警告
避免
context.read在buildWidget的方法内部调用。如果要优化重建,请提取在 Provider 中侦听的值。
这让我有点困惑。首先,文档给出了context.read在build方法内部使用的示例,然后给出了避免它的警告。为什么?
flutter ×10
flutter-provider ×10
dart ×7
flutter-bloc ×1
flutter-test ×1
riverpod ×1
socket.io ×1