如果我使用提供程序,如何在 App 启动时调用方法?
How to call method at App start if I am using 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"),
],
)
]),
],
);
}
}
您可以将 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()),
);
}
}
其他类保持不变。
另一种选择是将 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);
// ...
您可以在 TenderApiData
上添加一个构造函数来触发自定义逻辑:
class TenderApiData with ChangeNotifier {
TenderApiData() {
// TODO: call `getApiKey`
}
}
您可以使用 FutureProvider
值。
分离方法 api 到服务 (my_service.dart):
class MyService {
Future<String> 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) {
return json.decode(response.body)['access_token'];
}
}
}
然后从 MyApp 调用
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureProvider<String>.value(
value: MyService().getApiKey(),
child: HomePage(),
);
}
}
在主页中:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String token = Provider.of<String>(context);
return Scaffold();
}
}
您也可以只使用布尔标志 运行 方法仅一次。
提供商
import 'screen.abstract.dart';
class MyProvider with ChangeNotifier {
_hasInitialized = false;
// This will only be run once, when called
fetchApiOnce() {
if (_hasInitialized) {
return;
}
_hasInitialized = true;
/* DO STUFF */
}
}
我想完成 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"),
],
)
]),
],
);
}
}
您可以将 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()),
);
}
}
其他类保持不变。
另一种选择是将 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);
// ...
您可以在 TenderApiData
上添加一个构造函数来触发自定义逻辑:
class TenderApiData with ChangeNotifier {
TenderApiData() {
// TODO: call `getApiKey`
}
}
您可以使用 FutureProvider
值。
分离方法 api 到服务 (my_service.dart):
class MyService {
Future<String> 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) {
return json.decode(response.body)['access_token'];
}
}
}
然后从 MyApp 调用
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureProvider<String>.value(
value: MyService().getApiKey(),
child: HomePage(),
);
}
}
在主页中:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
String token = Provider.of<String>(context);
return Scaffold();
}
}
您也可以只使用布尔标志 运行 方法仅一次。
提供商
import 'screen.abstract.dart';
class MyProvider with ChangeNotifier {
_hasInitialized = false;
// This will only be run once, when called
fetchApiOnce() {
if (_hasInitialized) {
return;
}
_hasInitialized = true;
/* DO STUFF */
}
}