我有一个scopedModel类,可在其中提取数据。问题是,我无法使用拥有所有api请求的作用域模型从InitState方法呈现此数据。该方法正在被调用,但内部调用未被调用,因此页面的初始状态无法正确显示。
void initState() {
print("Check initState");
super.initState();
ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget child, MainModel model) {
print("Get into the scoped model");
model.fecthCars();
model.fecthCities();
model.fecthBuys(model.getUserDto.token);
print(model.getBuys().length);
return;
});
}
不会调用任何fetches(Api请求)。然后scopedModel返回一个小部件。我需要在第一次进入经理时进行更新,仅此而已。无需再次调用。这可能吗?还是应该在我需要的每个文件中对我的api请求进行硬编码?
更新
如果已经设置了作用域模型类,则可以在其内部设置这样的Future
mixin MyModel on Model {
Future<TypeToReturn> methodName(String param) async {
Uri uri = new Uri.http('serverUrl', 'api/call');
return await http.get(uri).then((http.Response response) {
final List<dynamic> myResponse= json.decode(response.body);
return myResponse;
}).catchError((error) {
print(error);
});
}
}
后期,您可以设置FutureBuilder
Widget _buildBody(BuildContext context, MainModel model) {
return FutureBuilder(
future: model.methodName(someString), //This is the method name above
builder: (context, AsyncSnapshot<TypeToReturn> snapshot) { //type u return
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
if (snapshot.data.length == 0)
return Center(
child: Text(
"No Data Found",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
),
),
);
return (create your own widget with the data inside the snapshot)
}
},
);
}
希望这会使我做得更多。
答案 0 :(得分:3)
我偶然发现以下解决方案:
在StatefulWidget的State类中,我这样做:
@override
void initState() {
super.initState();
// and here...
MyModel model = ScopedModel.of(context);
// now I can do with the model whatever I need to do:
Text someVar = model.initialText;
model.getValuesFromSomewhere();
// and so on
}
我认为,这是解决原始问题所指出的最简单方法。
答案 1 :(得分:2)
我认为您对ScopedModel和ScopedModelDescendant的观点有些误解。这些工作原理的基本思想是,使用有效模型创建ScopedModel,然后将其用于应用程序的其他部分。
但是,应该在其中一个小部件的build()函数中使用ScopedModelDescendant,并且还应将其作为小部件树的一部分。之所以没有调用您的提取方法,是因为它不在小部件树中,因此永远不会调用构建函数。
我建议改为将fetch
方法从模型中移出,并移入其他某个类(可能称为通信器或控制器之类)。接下来,我将进行建模,以便从该控制器进行异步调用的结果实例化该模型。
最后,我不建议实例化一个无效的模型然后在获取数据后就更改模型,我建议使用FutureBuilder
-这样,您就可以根据将来是否可以控制构建什么进行中,成功或失败。
所以看起来像这样(伪代码)。
StatefulWidget (MyApp or whatever you call it)
build =>
FutureBuilder(<fetch model data>, ...)
(if done)
ScopedModel<MainModel>
.... (whatever your code has here)
ScopedModelDescendant<MainModel>
(build using the model)
(if not done)
Loading.... (if needed)
如果您绝对希望模型始终存在,我仍然建议您在顶部的有状态小部件中进行访存,并简单地更改在其下面传递的模型,而不是在加载数据后修改现有模型。
答案 2 :(得分:1)
这是我的解决方案,希望对您有帮助
@override
void initState() {
super.initState();
User user = ScopedModel.of(this.context);
_controllerFirstName.text = user.userData['first_name'];
_controllerLastName.text = user.userData['last_name'];
}