当前位置: 首页 > 知识库问答 >
问题:

尝试从小部件树外部侦听提供程序公开的值

薛弘壮
2023-03-14

所以,我有一个项目在Flatter中,我试图建立一个卡片列表,其中的内容取决于我的OrderModel类,我试图使用Provider来实现这一点,但我得到了以下错误:

════════ 异常捕获调度程序库 ══════════════════════════

尝试从小部件树外部侦听提供程序公开的值。

这很可能是由调用Provider.of的事件处理程序(如按钮的onP)引起的,该事件处理程序没有传递liste: false

要修复,请写入:Provider。of(上下文,听:假);

它不受支持,因为当小部件树不关心值时,它可能会无意义地重建与事件处理程序关联的小部件。”包:provider/src/provider。dart':失败的断言:第193行第7位:“上下文”。物主debugBuilding | | listen==false | | | | | u debugisiniheritedProviderUpdate'

当抛出异常时,这是堆栈

#2 Provider.of包:提供者/src/provider.dart:193

#3_OrderHistoryState_onAfterBuild包:shinier_商店/屏幕/订单_历史记录。省道:60

#4_OrderHistoryState.build.包:shinier_store/屏幕/order_history.dart:67

#5日程安排_invokeFrameCallback包:flift/../scheduler/binding。省道:1102

#6 SchedulerBinding.handleDrawFrame包:flutter/.../调度器/binding.dart:1049...

═════════════════════════════════════════════════════════ 在_onAfterBuild()上调用提供程序的Stacktrace

I/flutter ( 3092): #0      _AssertionError._doThrowNew  (dart:core-patch/errors_patch.dart:42:39)
I/flutter ( 3092): #1      _AssertionError._throwNew  (dart:core-patch/errors_patch.dart:38:5)
I/flutter ( 3092): #2      Provider.of package:provider/src/provider.dart:193
I/flutter ( 3092): #3      _OrderHistoryState._onAfterBuild package:shinier_store/screens/order_history.dart:61
I/flutter ( 3092): #4      _OrderHistoryState.build.<anonymous closure> 
package:shinier_store/screens/order_history.dart:71
I/flutter ( 3092): #5      SchedulerBinding._invokeFrameCallback 
package:flutter/…/scheduler/binding.dart:1102
I/flutter ( 3092): #6      SchedulerBinding.handleDrawFrame 
package:flutter/…/scheduler/binding.dart:1049
I/flutter ( 3092): #7      SchedulerBinding._handleDrawFrame 
package:flutter/…/scheduler/binding.dart:957
I/flutter ( 3092): #8      _rootRun  (dart:async/zone.dart:1126:13)
I/flutter ( 3092): #9      _CustomZone.run  (dart:async/zone.dart:1023:19)
I/flutter ( 3092): #10     _CustomZone.runGuarded  (dart:async/zone.dart:925:7)
I/flutter ( 3092): #11     _invoke  (dart:ui/hooks.dart:259:10)
I/flutter ( 3092): #12     _drawFrame  (dart:ui/hooks.dart:217:3)

我不知道如何解决这个问题,因为我在我的提供者调用中添加了listen:false。我尝试使用WidgetBinding,因为我认为应该在构建完成后调用提供程序,但这似乎并没有解决问题。

代码如下:

OrderModel类

class OrderModel extends ChangeNotifier {
  List<Order> myOrders;
  bool isLoading = true;
  String errMsg;
  int page = 1;
  bool endPage = false;

  void getMyOrder({UserModel userModel}) async {
    try {
      isLoading = true;
      notifyListeners();
      myOrders = await WooCommerce().getMyOrders(userModel: userModel, page: 1);
      page = 1;
      errMsg = null;
      isLoading = false;
      endPage = false;
      notifyListeners();
    } catch (err) {
      errMsg =
          "There is an issue with the app during request the data, please contact admin for fixing the issues " +
              err.toString();
      isLoading = false;
      notifyListeners();
    }
  }

  void loadMore({UserModel userModel}) async {
    try {
      isLoading = true;
      page = page + 1;
      notifyListeners();
      var orders =
          await WooCommerce().getMyOrders(userModel: userModel, page: page);
      myOrders = [...myOrders, ...orders];
      if (orders.length == 0) endPage = true;
      errMsg = null;
      isLoading = false;
      notifyListeners();
    } catch (err) {
      errMsg =
          "There is an issue with the app during request the data, please contact admin for fixing the issues " +
              err.toString();
      isLoading = false;
      notifyListeners();
    }
  }
}

order_history.dart-国家级

class _OrderHistoryState extends State<OrderHistory> {
  void _onAfterBuild(BuildContext context){
     Provider.of<OrderModel>(context, listen: false)
        .getMyOrder(userModel: Provider.of<UserModel>(context));
  }

  @override
  Widget build(BuildContext context) {
    var formatter = DateFormat('dd-MM-yyyy');
    var model = Provider.of<OrderModel>(context);
    WidgetsBinding.instance.addPostFrameCallback((_) => _onAfterBuild(context));

    return Scaffold(
      appBar: AppBar(
          title: Text(
            'Order History',
            style: TextStyle(fontWeight: FontWeight.bold),
          ),
          elevation: 0.0),
      body: model.myOrders == null ? Center() :
      Padding(
        padding: const EdgeInsets.all(10.0),
        child: ListView.separated(
          separatorBuilder: (_, __) => SizedBox(height: 10.0),
          itemCount: model.myOrders.length,
          itemBuilder: (context, index) {
            String stat = model.myOrders[index].status;
            return Card(
              color: _buildColor(stat),
              elevation: 3.5,
              ...
  }
}

main.dart-构建方法

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => UserModel()),
        ChangeNotifierProvider(create: (_) => CartModel()),
        ChangeNotifierProvider(create: (_) => SearchModel()),
        ChangeNotifierProvider(create: (_) => OrderModel()),
      ],
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primaryColor: Colors.white,
          backgroundColor: Colors.white,
          canvasColor: Colors.white,
        ),
        home: MainTabs(),
        debugShowCheckedModeBanner: false,
        localizationsDelegates: [
          i18n,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: i18n.supportedLocales,
      ),
    );
  }

共有2个答案

雷硕
2023-03-14

我还发现,即使没有监听参数,使用BlocProvider似乎也能解决这个问题。但是在这种情况下,您将使用BLOC进行状态管理。

在所有情况下,我都使用var yyystate=BlocProvider。(上下文);我总是添加listen参数。

壤驷坚
2023-03-14

这个错误似乎指出了这两行代码是导致这个问题的原因。

#3 _OrderHistoryState._onAfterBuild package:shinier_store/screens/order_history.dart:60

#4 _OrderHistoryState.build. package:shinier_store/screens/order_history.dart:67

您提供的重现是不完整的,我只能猜测所需的标志听:false已添加到_onAfterBuild()。但是,错误日志指出var Model=Provider.of

如果您仍然有问题,一个有效的最小重现将有助于我们理解为什么会发生这种行为。

 类似资料:
  • 我正试图实现这一愿景。[1]: https://i.stack.imgur.com/6COFI.png这是我第一次使用提供商。同样的代码也适用于todo应用程序。但我无法使用此应用程序的代码。我尝试过修改代码,但徒劳无功。 错误消息是:EXCEPTION CAUGHT BY GESTURE ╞═════════════════════════════════════════════════════

  • 如何使用从辅助外部存储器提供文件? 的当前实现只处理 看来,没有办法定义一个

  • 问题内容: 当在下拉组件外部单击时,我想关闭下拉菜单。 我怎么做? 问题答案: 在我添加的元素中,像这样: 然后在父母中,我这样做: 该是一个布尔值,当显示在我的情况下,日历和隐藏它。

  • 我想为我的客户和API建立契约测试。我的API不能在本地运行,所以我希望能够在部署到生产之前,针对已部署的API临时版本运行提供程序测试。 我在网上看到的提供程序测试的大多数示例都使用了localhost。当尝试对我部署的HTTPSendpoint运行提供程序测试时,测试失败,显示。是不支持HTTPS协议,还是我遗漏了什么? 使用pact-provider-verifier cmd line工具工

  • 我有一个注册了< code>Keycloak的外部< code>openidconnect身份提供者。当客户端应用程序试图访问受保护的资源时,它会被重定向到< code>KeyCloak登录页面。在登录页面上,我启用了外部< code>openidconnect提供程序按钮。一旦用户单击该按钮,他将被带到外部身份提供者(即identityserver3实例)。外部提供商对用户进行身份验证并发回一个

  • 我有一个时钟小部件Android应用程序,我现在正试图更新到API 26的要求。 到目前为止,我使用了一个后台服务,它在启动时在其方法a中注册,以接收系统广播,例如。然后,这项服务在屏幕关闭时暂停时钟,在屏幕重新打开时唤醒时钟,以节省电池。 在Oreo中,这类服务似乎不是一个选项,因为它必须在前台运行,并带有一个对用户没有意义的通知。此外,据我在文档中看到的,也帮不上我的忙,因为我没有发现可以将作