Dmi*_*kov 8 flutter flutter-provider
我想完成get对服务器的请求,以便在我的应用程序启动时获取数据。我阅读了几个描述构建小部件后如何运行方法的主题。但它们都是描述provider不使用时的情况。而且我不确定在小部件中执行此请求是否是个好主意。
我尝试了几种方法,但没有成功。这是我的代码:
void main() async {
runApp(new MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierProvider<TenderApiData>(
builder: (_) => TenderApiData(), child: HomePage()),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(), body: MainContainer());
}
}
class TenderApiData with ChangeNotifier {
String access_token;
List<Map<String, String>> id_names;
String access_token_url = "https://...";
getApiKey() async { // I need to call this method at app start up
var response = await http
.post(access_token_url, headers: {"Accept": "application/json"});
if (response.statusCode == 200) {
access_token = json.decode(response.body)['access_token'];
notifyListeners();
}
}
}
class MyTestWidget extends StatefulWidget {
MyTestWidgetState createState() => MyTestWidgetState();
}
class MyTestWidgetState extends State<MyTestWidget> {
bool isKeyGetted = false;
// before I used this when I extracted data on click event.
// I am not sure that it's needed now
@override
void didChangeDependencies() {
if (!isKeyGetted) {
Provider.of<TenderApiData>(context).getApiKey();
isKeyGetted = !isKeyGetted;
}
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
if (!isKeyGetted) {
Provider.of<TenderApiData>(context).getApiKey();
isKeyGetted = !isKeyGetted;
}
var result = Provider.of<TenderApiData>(context).access_token;
var test = Provider.of<TenderApiData>(context).id_names;
return Column(
children: <Widget>[
RaisedButton(
onPressed: Provider.of<TenderApiData>(context).getRegionsList,
child: Text("get regions"),
),
],
);
}
}
class MainContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Table(
children: [
TableRow(children: [
Row(
children: <Widget>[
Container(child: MyTestWidget()),
Container(child: Text("Regions"),),
Expanded(child: SelectRegions(), )
],
)
]),
TableRow(children: [
Row(
children: <Widget>[
Text("Label"),
Text("Value"),
],
)
]),
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以存储TenderApiData为 的成员MyApp,在构造函数中进行启动调用MyApp并将现有实例传递给后代。
其外观如下:
class MyApp extends StatelessWidget {
final TenderApiData _tenderApiData = TenderApiData();
MyApp() {
_tenderApiData.getApiKey();
};
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierProvider<TenderApiData>(
builder: (_) => _tenderApiData, child: HomePage()),
);
}
}
Run Code Online (Sandbox Code Playgroud)
其他类别保持不变。
另一种选择是将TenderApiData作为构造函数参数传递给MyApp,使其更易于测试。
void main() {
final TenderApiData tenderApiData = TenderApiData();
tenderApiData.getApiKey(); // call it here or in MyApp constructor - now it can be mocked and tested
runApp(MyApp(tenderApiData));
}
class MyApp extends StatelessWidget {
final TenderApiData _tenderApiData;
MyApp(this._tenderApiData);
// ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4755 次 |
| 最近记录: |