Flutter Provider仅在热重装后显示结果

时间:2020-10-23 10:40:52

标签: firebase flutter google-cloud-firestore provider flutter-provider

我是一个初学者,我正在根据提供程序的教程构建一个应用程序。逻辑是,当您单击“类别”窗口小部件时,它应将您带到一个包含该类别产品的页面。该逻辑按预期工作,除了我必须首先刷新代码以显示结果。坦白地说,我不知道自己在做什么错。

从主页上,使用“列表视图”构建器呈现“类别”小部件

Container(
                height: 75,
                child: ListView.builder(
                  scrollDirection: Axis.horizontal,
                  itemCount: categoryProvider.categories.length,
                  itemBuilder: (context, index) {
                    return GestureDetector(
                      onTap: () async {
                        await productProvider.loadProductsByCategory(
                            categoryName:
                                categoryProvider.categories[index].name);
                        changeScreen(
                            context,
                            CategoryScreen(
                                categoryModel:
                                    categoryProvider.categories[index]));
                      },
                      child: CategoriesWidget(
                          category: categoryProvider.categories[index]),
                    );
                  },
                ),
              )

Main.Dart

我正在听这样的提供商

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: AppProvider()),
        ChangeNotifierProvider.value(value: UserProvider.initialize()),
        ChangeNotifierProvider.value(value: CategoryProvider.initialize()),
        ChangeNotifierProvider.value(value: MarketProvider.initialize()),
        ChangeNotifierProvider.value(value: ProductProvider.initialize()),
      ],
      child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Akatale',
          theme: ThemeData(
            primaryColor: Colors.black,
          ),
          home: ScreenController())));
}

class ScreenController extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final auth = Provider.of<UserProvider>(context);

    switch (auth.status) {
      case Status.Uninitialized:
        return Loading();
      case Status.UnAuthenticated:
      case Status.Authenticating:
        return SignInScreen();
      case Status.Authenticated:
        return MainScreen();
      default:
        return SignInScreen();
    }
  }
}

产品服务

通过此操作,我可以按类别名称从firestore中获取产品,并将其添加到列表中

class ProductService extends ChangeNotifier {
  String collection = "products";
  Firestore _firestore = Firestore.instance;


  Future<List<ProductModel>> getProductsByCategory({String category}) async {
    List<ProductModel> products = [];
    _firestore
        .collection(collection)
        .where("category", isEqualTo: category)
        .getDocuments()
        .then((result) {
      for (DocumentSnapshot product in result.documents) {
        products.add(ProductModel.fromSnapshot(product));
      }
    });
    return products;
  }
}

产品提供商

这里有一些在小部件中调用的公共方法

class ProductProvider with ChangeNotifier {
  ProductService _productService = ProductService();
  List<ProductModel> products = [];
  List<ProductModel> productsByCategory = [];


  ProductProvider.initialize() {
    _loadProducts();
   
  }

  //Private method Load products to List
  Future _loadProducts() async {
    products = await _productService.getProducts();
    notifyListeners();
  }

  //public method to Load products to List by category
  Future loadProductsByCategory({String categoryName}) async {

    productsByCategory =
        await _productService.getProductsByCategory(category: categoryName);

    notifyListeners();
  }
}

类别页面

这是根据所选类别呈现产品的地方

class CategoryScreen extends StatelessWidget {
  final CategoryModel categoryModel;

  const CategoryScreen({Key key, this.categoryModel}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    final productProvider = Provider.of<ProductProvider>(context);
    return Scaffold(
      body: SafeArea(
          child: ListView(
        children: [
          Text(categoryModel.name),
          Column(
            children: productProvider.productsByCategory.map((item) {
              return GestureDetector(
                  onTap: () {
                    //Load details page
                  },
                  child: ProductWidget(
                    product: item,
                  ));
            }).toList(),
          ),
        ],
      )),
    );
  }
}

显示空白页 Categories page

但是在点击“热加载”后,产品就会出现 enter image description here

1 个答案:

答案 0 :(得分:1)

getProductsByCategory的{​​{1}}中,您不等待ProductsService。 因此,尽管文档将被加载,但它实际上已经完成加载之前已经在模型中调用notifyListeners。 因此,当您使用hotreload进行重建时,它们会出现

要解决此问题,只需等待服务中的getDocuments