Flutter Provider 仅在热重载后显示结果
Flutter Provider showing results ONLY after Hot Reload
我是初学者,我正在按照使用提供程序的教程构建应用程序。其逻辑是,当您单击“类别”小部件时,它应该会将您带到包含该类别产品的页面。逻辑按预期工作,除了我必须先刷新代码才能显示结果。坦率地说,我不知道我做错了什么。
在主页中,类别小部件是使用列表视图生成器呈现的
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;
}
}
产品提供商
这里我有 public 个方法可以在小部件中调用
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(),
),
],
)),
);
}
}
显示空白页
但是在热重载时,产品出现
在 getProductsByCategory
中,在 ProductsService
中,您没有在等待 getDocuments
。
因此,虽然文档将被加载,但在实际完成加载之前,它已经在模型中调用了 notifyListeners。
因此,当您使用 hotreload 进行重建时,它们会出现
要解决此问题,只需等待服务中的 getDocuments
我是初学者,我正在按照使用提供程序的教程构建应用程序。其逻辑是,当您单击“类别”小部件时,它应该会将您带到包含该类别产品的页面。逻辑按预期工作,除了我必须先刷新代码才能显示结果。坦率地说,我不知道我做错了什么。
在主页中,类别小部件是使用列表视图生成器呈现的
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;
}
}
产品提供商
这里我有 public 个方法可以在小部件中调用
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(),
),
],
)),
);
}
}
显示空白页
但是在热重载时,产品出现
在 getProductsByCategory
中,在 ProductsService
中,您没有在等待 getDocuments
。
因此,虽然文档将被加载,但在实际完成加载之前,它已经在模型中调用了 notifyListeners。
因此,当您使用 hotreload 进行重建时,它们会出现
要解决此问题,只需等待服务中的 getDocuments