У меня есть простое приложение с двумя файлами dart: main.dart и bukalapak.dart
В демонстрационных целях в приложении есть только два виджета Future Text (). В основном один текстовый виджет получает имя определенного html, другой виджет получает общее количество того же html. Не спрашивайте, почему, но будущий конструктор для "name" должен быть в отдельном виджете с отслеживанием состояния в bukalapak.dart. Мой вопрос в том, как я могу дождаться, пока html не станет нулевым, а затем отобразить общий текстовый виджет, потому что я могу легко просто снова вызвать URL-адрес, но это будет делать в два раза больше работы. Я хочу только один раз вызвать http.get.
Вот код для main.dart:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
Bukalapak bukalapak = Bukalapak();
return Scaffold(
appBar: AppBar(
title: Text('data'),
),
body: Container(
child: Column(
children: <Widget>[
RandomWidget(
bukalapak: bukalapak,
),
FutureBuilder(
builder: (context, snapshot) {
return Container(
color: Colors.grey,
height: 28.0,
padding: EdgeInsets.only(left: 20.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text('Total results: ${snapshot.data}')),
);
},
future: bukalapak.getTotal(),
)
],
),
),
);
}
}
Код для bukalapak.dart:
class Bukalapak {
var html;
Future<dynamic> getTotal() async {
// wait until html != null, then perform this
var a = html.querySelectorAll(
'#display_product_search > div.product-pagination-wrapper > div.pagination > span.last-page');
dynamic total = int.parse(a[0].text) * 50;
total = '$total'.replaceAllMapped(
new RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},');
return total;
}
Future<dynamic> getName() async {
http.Response response = await http.get(
'https://www.bukalapak.com/products/s?from=omnisearch&from_keyword_history=false&page=0&search%5Bkeywords%5D=paper&search_source=omnisearch_organic&source=navbar&utf8=✓');
if (response.statusCode == 200) {
String data = response.body;
html = parse(data);
var nameElement = html.querySelector(
'li.col-12--2 > div.product-card > article > div.product-media > a');
String title = nameElement.attributes['title'];
return title;
} else {
throw Exception('Bukalapak error: statusCode= ${response.statusCode}');
}
}
}
class RandomWidget extends StatefulWidget {
RandomWidget({this.bukalapak});
final Bukalapak bukalapak;
@override
_TextState createState() => _TextState();
}
class _TextState extends State<RandomWidget> {
@override
Widget build(BuildContext context) {
return FutureBuilder(
builder: (context, snapshot) {
return Container(
color: Colors.grey,
height: 28.0,
padding: EdgeInsets.only(left: 20.0),
child: Align(
alignment: Alignment.centerLeft,
child: Text('Name results: ${snapshot.data}')),
);
},
future: widget.bukalapak.getName(),
);
}
}