【问题标题】:FLUTTER: How to load data before build() methodFLUTTER:如何在 build() 方法之前加载数据
【发布时间】:2020-11-03 08:49:16
【问题描述】:

你能帮帮我吗?我需要将来自云火库的数据加载到 List 中,并且在颤振运行 build() 方法之前我需要它。这个想法是让这个列表准备好使用来自 StreamBuilder 的值。在下一张图片中,我解释了我想要解决的问题:

视觉小工具:https://i.stack.imgur.com/fv0eg.jpg

现在我使用 Futures 从 Cloud Firestore 请求品牌,它可以工作,但我使用异步方法,所以当我准备好列表时,小部件已经呈现,我无法在列表中搜索,因为 StreamBuilder 时为空解决。我知道我可以向 StreamBuilder 的构建者请求特定品牌的数据,但我认为有更好的方法可以做到这一点,因为品牌集合不会改变,我必须在每个 StreamBuilder 事件中请求品牌数据,它可以工作,但我对那个解决方案感觉不太好。因此,如果我能在开始时获得一个列表,我就可以保存许多从 Cloud Firestore 获取品牌数据的请求。

代码小部件:

class _GeneralInventoryPageState extends State<GeneralInventoryPage> {
  
  ServiceFirestore _serviceFirestore = new ServiceFirestore();
  static final _appResources = new AppResources(); 
  Stream<QuerySnapshot> _streamGenericProducts; // STREAM OF PRODUCTS OF CLOUD FIRESTORE
  List<MapMarca> _allBrands; // THIS IS THE LIST I WANT TO FILL WITH BRANDS OF CLOUD FIRESTORE
  
  @override
  void initState() { 
    super.initState();
    final productCollectionName = _appResources.getResource("productCollectionName");
    _streamGenericProducts = _serviceFirestore.serviceGetCollection(productCollectionName); // initialize Stream
    _allBrands = new List<MapMarca>(); //initialize List<brand>
    _getAllBrands();
  }
  
 void _getAllBrands() async {
    var marcasRaw = await _serviceFirestore.serviceGetUniqueDocumentByCollectionName(collectionName, documentId);
    if(marcasRaw == null){
      print("Error");
    }
    else{
      ModelMarca marcas  = ModelMarca.fromMap(Map<String, dynamic>.from(marcasRaw)); //decoding brands
      this._allBrands = marcas.listBrand; // set the List<brand>
    }
  }

  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
      appBar: AppBar(
        title: Text('Inventario')
      ),
      body: Container(
        child: StreamBuilder(
          stream: this._streamGenericProducts,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (!snapshot.hasData) {
              return CircularProgressIndicator();
            }
            else {
              List<ModelProduct> genericProductList = [];
              QuerySnapshot  querySnapshot = snapshot.data;
              querySnapshot.documents.forEach((doc){
                final genericProduct = ModelProduct.fromMap(Map<String,dynamic>.from(doc.data));
                genericProduct.strIdRecord = doc.documentID;
                genericProductList.add(genericProduct);
              });
              return createProductListView(context, genericProductList);
            }
            
          },
          )
        ),  
    );
  }
 
  //I use createProductListView to Create every product section detail (this method is not important)
  Widget createProductListView(BuildContext context, List<ModelProduct> genericProductList) {
    return ListView(
      children: List<Widget>.from(genericProductList.map((genericProducto)=>createProductListTile(context,genericProducto)).toList())
    );
  }
   
  // Here I build every single Product Detail, I simplify the code, please look how I get the Brand Name
  Widget createProductListTile(BuildContext context, ModelProduct genericProduct) {
    return Column(
      children: <Widget>[
        ListTile(
          title: Column(
            children: <Widget>[
              Row(
                children: <Widget>[
                  Container(
                    //code for getting the product image
                ),
                ]
              ),
              // some code about product info....
              Row(
                children: <Widget>[
                  Expanded(child: Text("Marca: ${_getBrandName(brandCode: genericProduct.strProductBrand)}")) //HERE I ALWAYS GET "NO BRAND INFO "
                ],
              ),
              // some code about product info...
            ],
          ),
        ),
      ],
    );
  }

  String _getBrandName({String brandCode}) {
    MapMarca marca = _searchBrand(brandId: brandCode);
    if(marca == null) {
      return "NO BRAND INFO"; // this is what is get when I run my app in the Brand Field
    }
    else {
      return marca.valor;
    }
  }
}

【问题讨论】:

    标签: firebase flutter google-cloud-firestore future


    【解决方案1】:

    尝试在 didchangeDependenices 中加载您的数据:-

     @override
     void didChangeDependencies() {
      super.didChangeDependencies();
     
     //try to load all your data in this method :)
    
     }
    

    【讨论】:

      【解决方案2】:

      尝试使用FutureBuilder

      FutureBuilder(
          future: *Your Data to Load*,
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            return *Your Widgets*;
       })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-15
        • 2018-05-22
        • 2021-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多