Flutter / Dart 使用带后代和 Navigator 的 Scoped Model
Flutter / Dart using Scoped Model with descendants and Navigator
我从昨天开始就一直在努力解决这个问题 - 我在选项卡控制器 (ScreenTabs) 中创建新的 ScopedModel obj,然后将它传递给 BottomNavigationBar 中的多个选项卡(第一级后代,例如:ScreenBook)将每个选项卡包装为 ScopedModelDescendant。到目前为止一切顺利 - 一切都按预期工作。
问题出现了,在我的一个选项卡中,我想导航到它的子项(第二级后代,例如:ScreenBookDetails)并在那里使用 ScopedModel。我已经尝试过使用 ScopedModelDescendant 和 ScopedModel.of(context) 但没有成功 - 每次都出现错误:无法找到正确的 ScopedModel。
我的代码(为简洁起见跳过了一些):
选项卡控制器
...
class ScreenTabsState extends State<ScreenTabs> {
ModelTabs modelTabs = ModelTabs(); //new Model object
var screens = [new ScreenHome(),new ScreenBook(),];
@override
Widget build(BuildContext context) {
return ScopedModel<ModelTabs>(
model: modelTabs,
child: Scaffold(...)
body: Builder (builder: (context) => Container(child:
screens.elementAt(selectedIndex),)),
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedIndex,
items: [...],
onTap: onTabTapped,
),)...}
ScreenBook(第一个 ddescendant - ScpodedModel 按预期工作)
...
class ScreenBookState extends State<ScreenBook> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: ScopedModelDescendant<ModelTabs>(builder: (context, child, model) {
print(TAG + "model status:" + model.status.toString());
return model.status == Status.LOADING ? MyCircularProgressIndicator() :
Builder (builder: (context) =>
Card(...
child: InkWell(
onTap: (){
Navigator.of(context).pushNamed("/ScreenBookDetails");},))}}
ScreenBookDetails(第一个后代 - 错误)
...
class ScreenBookDetailsState extends State<ScreenBookDetails>{
@override
Widget build(BuildContext context) {
return Scaffold(
body: ScopedModelDescendant<ModelTabs>(builder: (context, child, model) {
print(TAG + "scoped model status: " + model.status.toString()); //Error: Could not find the correct ScopedModel.
return model.status == Status.LOADING ? MyCircularProgressIndicator() : Builder(builder: (context) => Column(...)
...
有人能告诉我解决这个问题的正确方法吗?我是 Dart 和 Flutter 的新手,所以在 ScreenSplashScreen 中创建 ScopedModel obj 然后导航到 ScreenLogIn 并尝试在那里使用它时,我遇到了类似的问题,所以可能有一些我没有清楚地理解的东西。
谢谢! :)
终于在 ScopedModel 的 Github 支持的帮助下找到了如何处理包括 Navigator 的 ScopedModel - 关键是在 build(BuildContext) 之外创建一个 ScopeModel 实例,然后通过下一个屏幕的构造函数传递该实例, 比如:
class HomePage extends StatelessWidget {
SampleScopedModel model = SampleScopedModel();
@override
Widget build(BuildContext context) {
return ScopedModel<SampleScopedModel>(
model: model,
child: Scaffold(
body: Container(),
floatingActionButton: FloatingActionButton(onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => NextPage(model))
);
}),
),
);
}
}
class NextPage extends StatelessWidget {
final SampleScopedModel model;
NextPage(this.model);
@override
Widget build(BuildContext context) {
return ScopedModel<SampleScopedModel>(
model: model,
child: Scaffold(
body: ScopedModelDescendant<SampleScopedModel>(
builder: (context, child, model) {
return Text(model.payload.toString());
})
),
);
}
}
我从昨天开始就一直在努力解决这个问题 - 我在选项卡控制器 (ScreenTabs) 中创建新的 ScopedModel obj,然后将它传递给 BottomNavigationBar 中的多个选项卡(第一级后代,例如:ScreenBook)将每个选项卡包装为 ScopedModelDescendant。到目前为止一切顺利 - 一切都按预期工作。
问题出现了,在我的一个选项卡中,我想导航到它的子项(第二级后代,例如:ScreenBookDetails)并在那里使用 ScopedModel。我已经尝试过使用 ScopedModelDescendant 和 ScopedModel.of(context) 但没有成功 - 每次都出现错误:无法找到正确的 ScopedModel。
我的代码(为简洁起见跳过了一些):
选项卡控制器
...
class ScreenTabsState extends State<ScreenTabs> {
ModelTabs modelTabs = ModelTabs(); //new Model object
var screens = [new ScreenHome(),new ScreenBook(),];
@override
Widget build(BuildContext context) {
return ScopedModel<ModelTabs>(
model: modelTabs,
child: Scaffold(...)
body: Builder (builder: (context) => Container(child:
screens.elementAt(selectedIndex),)),
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedIndex,
items: [...],
onTap: onTabTapped,
),)...}
ScreenBook(第一个 ddescendant - ScpodedModel 按预期工作)
...
class ScreenBookState extends State<ScreenBook> {
@override
Widget build(BuildContext context) {
return new Scaffold(
body: ScopedModelDescendant<ModelTabs>(builder: (context, child, model) {
print(TAG + "model status:" + model.status.toString());
return model.status == Status.LOADING ? MyCircularProgressIndicator() :
Builder (builder: (context) =>
Card(...
child: InkWell(
onTap: (){
Navigator.of(context).pushNamed("/ScreenBookDetails");},))}}
ScreenBookDetails(第一个后代 - 错误)
...
class ScreenBookDetailsState extends State<ScreenBookDetails>{
@override
Widget build(BuildContext context) {
return Scaffold(
body: ScopedModelDescendant<ModelTabs>(builder: (context, child, model) {
print(TAG + "scoped model status: " + model.status.toString()); //Error: Could not find the correct ScopedModel.
return model.status == Status.LOADING ? MyCircularProgressIndicator() : Builder(builder: (context) => Column(...)
...
有人能告诉我解决这个问题的正确方法吗?我是 Dart 和 Flutter 的新手,所以在 ScreenSplashScreen 中创建 ScopedModel obj 然后导航到 ScreenLogIn 并尝试在那里使用它时,我遇到了类似的问题,所以可能有一些我没有清楚地理解的东西。
谢谢! :)
终于在 ScopedModel 的 Github 支持的帮助下找到了如何处理包括 Navigator 的 ScopedModel - 关键是在 build(BuildContext) 之外创建一个 ScopeModel 实例,然后通过下一个屏幕的构造函数传递该实例, 比如:
class HomePage extends StatelessWidget {
SampleScopedModel model = SampleScopedModel();
@override
Widget build(BuildContext context) {
return ScopedModel<SampleScopedModel>(
model: model,
child: Scaffold(
body: Container(),
floatingActionButton: FloatingActionButton(onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => NextPage(model))
);
}),
),
);
}
}
class NextPage extends StatelessWidget {
final SampleScopedModel model;
NextPage(this.model);
@override
Widget build(BuildContext context) {
return ScopedModel<SampleScopedModel>(
model: model,
child: Scaffold(
body: ScopedModelDescendant<SampleScopedModel>(
builder: (context, child, model) {
return Text(model.payload.toString());
})
),
);
}
}