【问题标题】:Flutter bloc pattern repeat calling function many timesFlutter bloc 模式多次重复调用函数
【发布时间】:2020-03-11 17:49:20
【问题描述】:

我正在尝试在颤振应用程序中使用 bloc 模式我在返回 Scaffold() 之前在构建函数的主体内编写代码;如下

@override
  Widget build(BuildContext context) {
    final ProductsController pController = Provider.of<ProductsController>(context);
    pController.addProducts();
    return Scaffold();
}

一切都是完美的,但功能 addPrducts() 调用了太多次它看起来下面的代码重复了很多次

pController.addProducts();

这是 ProductsContoller 类的结构

class ProductsController extends ChangeNotifier {
List<Products> _products=List();
AppDatabase appDB=AppDatabase();
  List<Products> get products=>_products;
addProducts() {
      appDB.getFromTable(AppDatabase.TBL_PRODUCTS).then((rows){
      rows.forEach((row){
        Products product=Products.fromJson(row);
        _products.add(product);


      });
      notifyListeners();
    });
  }
}

【问题讨论】:

  • 你在构建方法中使用setState吗?
  • 不,我使用 bloc 来避免使用 setState

标签: flutter provider bloc


【解决方案1】:

您必须定义在其他类(有状态或无状态)中使用您的列表的小部件。

例如,如果您在 ListView 中使用 List,则必须为您的 ListView 创建一个无状态类,并在该类中监视列表。

    class ProductList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 260,
        childAspectRatio: 3 / 4.6,
      ),
      itemCount: context.watch<ProductsController >().productPjo.listProduct.length,
      shrinkWrap: true,
      itemBuilder: (_, i) {
        return  ItemProduct(context.watch<ProductsController >().productPjo.listProduct[i]);
      },
    );
  }
}

【讨论】:

    【解决方案2】:

    如果你想做一些操作,比如在有状态小部件中只获取一次屏幕数据,那么你可以使用 void didChangeDependencies() 和布尔标志。

    didChangeDependencies() 也会在 initState 之后立即调用。 当此 State 对象的依赖项发生更改时也会调用。从此方法调用 BuildContext.dependOnInheritedWidgetOfExactType 是安全的。

    final ProductsController pController
    var _isLoadingForFirstTime = true;
    
    @override
    void initState() {
        super.initState();
    }
    
    @override
      void didChangeDependencies() {
        if (_isLoadingForFirstTime) {
           pController = Provider.of<ProductsController>(context);
           pController.addProducts();
        }
        _isLoadingForFirstTime = false;
        super.didChangeDependencies();
    }
    
    @override
      Widget build(BuildContext context) {
        return Scaffold(); // You Screen contents here
    }
    

    【讨论】:

      【解决方案3】:

      如果你的函数应该只被调用一次,你应该尝试覆盖initState() 方法并在那里调用它。如果您的类扩展了 StatefulWidget 您的 build(BuildContext context) 方法可能会被多次调用。

      final ProductsController pController
      
      @override
      void initState() {
          pController = Provider.of<ProductsController>(context);
          pController.addProducts();
      
          super.initState();
      }
      

      【讨论】:

      • 是什么导致构建方法多次调用??
      • 框架在多种不同情况下调用此方法: 在调用 initState 之后。调用 didUpdateWidget 之后。在收到对 setState 的调用后。在此 State 对象的依赖项发生更改后(例如,先前构建所引用的 InheritedWidget 发生更改)。在调用 deactivate 然后将 State 对象重新插入到另一个位置的树中。 api.flutter.dev/flutter/widgets/State/build.html
      • 你的方式给这个异常 inheritFromWidgetOfExactType(_Provider) 或 inheritFromElement() 被称为 I/flutter (6563):在 _ReportState.initState() 完成之前。 _ReproSate 是我的 Class 继承的 statefulWidget
      猜你喜欢
      • 2019-02-07
      • 2019-11-20
      • 2021-02-28
      • 2019-07-19
      • 1970-01-01
      • 2019-10-24
      • 1970-01-01
      • 2019-12-26
      • 2019-06-13
      相关资源
      最近更新 更多