【问题标题】:How to run the setState() after executing insert or delete of the moor in flutter如何在颤动中执行插入或删除moor后运行setState()
【发布时间】:2020-11-23 15:11:52
【问题描述】:

如果你触摸心形图标,我想在 Moor 数据库中插入或删除产品类并将心形图标更改为 setState()

插入或删除执行良好,但心形图标似乎没有变化,因为在插入或删除期间已执行 setState()。

如果您能告诉我我的方法是否错误,或者是否有比使用“流生成器”更好的方法,我将不胜感激。

感谢您阅读我的问题。

Widget setFavorite() {
ProductsDao productsDao = Provider.of<AppDatabase>(context).productsDao;
return StreamBuilder<List<mf.QueryRow>>(
  stream: productsDao
      .customSelect(
          "SELECT * FROM Products WHERE firestoreid LIKE '${widget.product.firestoreid}'")
      .watch(),
  builder:
      (BuildContext context, AsyncSnapshot<List<mf.QueryRow>> snapshot) {
    if (snapshot.hasError) {
      print(snapshot.error);
      return new Text('Error: ${snapshot.error}');
    }
    switch (snapshot.connectionState) {
      case ConnectionState.waiting:
        return Text("");
      default:
        return Positioned(
          right: 0,
          bottom: 0,
          child: Padding(
            padding: EdgeInsets.all(5),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                GestureDetector(
                  onTap: () {
                    setState(() {
                      snapshot.data.isEmpty
                          ? productsDao.insertProduct(this.widget.product)
                          : productsDao.deleteProduct(this.widget.product);
                    });
                  },
                  child: Icon(
                    snapshot.data.isEmpty
                        ? Icons.favorite_border
                        : Icons.favorite,
                    color: Colors.pink,
                  ),
                ),
              ],
            ),
          ),
        );
    }
  },
);

}

【问题讨论】:

    标签: flutter dart setstate flutter-moor


    【解决方案1】:

    您可以尝试使用 await 等待数据库完成:

              onTap: () async {
                  snapshot.data.isEmpty
                      ? await productsDao.insertProduct(this.widget.product)
                      : await productsDao.deleteProduct(this.widget.product);
                setState(() {}
                });
              },
    

    【讨论】:

    • 感谢您的回答。但是,图标仍然没有改变。还有其他方法吗?
    • 也许你应该使用状态管理插件。我使用 MobX,更新我的 Moor 数据库时,我调用 MobX 函数和 MobX,验证值,存储它并在 UI 上更改它
    【解决方案2】:

    我不确定您是如何使用插入方法的,但是如果您使用的是提供程序,则需要使用一个可以更新状态并使用 notifiyListeners() 的函数。 当您使用通知侦听器时,您甚至不需要 setstate,它会更新所有值。

    class AppDatabase extends ChangeNotifier {
      
      ProductsDao _productsDao;
      
      ProductsDao get productsDao => _productsDao;
      
      void insertProduct(value){
         this._productsDao.insertProduct(value);
            notifiyListeners();
          }
    
    void deleteProduct(value){
        this._productsDao.deleteProduct(value);
        notifiyListeners();
      }
    
        }
    

    现在您应该使用提供程序 insertProduct 来刷新您的值的状态。

    Widget setFavorite() {
    AppDatabase appState = Provider.of<AppDatabase>(context);
    return StreamBuilder<List<mf.QueryRow>>(
      stream: appState.productsDao
          .customSelect(
              "SELECT * FROM Products WHERE firestoreid LIKE '${widget.product.firestoreid}'")
          .watch(),
      builder:
          (BuildContext context, AsyncSnapshot<List<mf.QueryRow>> snapshot) {
        if (snapshot.hasError) {
          print(snapshot.error);
          return new Text('Error: ${snapshot.error}');
        }
        switch (snapshot.connectionState) {
          case ConnectionState.waiting:
            return Text("");
          default:
            return Positioned(
              right: 0,
              bottom: 0,
              child: Padding(
                padding: EdgeInsets.all(5),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: <Widget>[
                    GestureDetector(
                      onTap: () {
                        setState(() {
                          snapshot.data.isEmpty
                              ? appState.insertProduct(this.widget.product)
                              : appState.deleteProduct(this.widget.product);
                        });
                      },
                      child: Icon(
                        snapshot.data.isEmpty
                            ? Icons.favorite_border
                            : Icons.favorite,
                        color: Colors.pink,
                      ),
                    ),
                  ],
                ),
              ),
            );
        }
      },
    );
    

    这将刷新您在 ui 中的值。

    希望对您有所帮助。

    【讨论】:

    • 感谢您的回答。 Provider 用于访问 moor 数据库中的 productDao 类。没有其他操作
    • 您应该在应用数据库中创建一个方法,该方法将使用新值获取插入并将其插入您拥有的列表中,然后调用notifiyListeners。
    • 我已经用代码更新了我的答案,让你刷新用户界面。您必须使用您的提供者来刷新它,而不是 ProductsDao 对象。
    猜你喜欢
    • 2019-04-20
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-14
    • 1970-01-01
    相关资源
    最近更新 更多