Flutter / Dart 使用具有后代和 Navigator 的 Scoped Model

Posted

技术标签:

【中文标题】Flutter / Dart 使用具有后代和 Navigator 的 Scoped Model【英文标题】:Flutter / Dart using Scoped Model with descendants and Navigator 【发布时间】:2019-09-28 08:44:25 【问题描述】:

从昨天开始我一直在努力解决这个问题 - 我正在标签控制器 (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(第一个后代 - 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 并尝试在那里使用它时,我可能会遇到类似的问题。

谢谢! :)

【问题讨论】:

【参考方案1】:

在 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());
          )
        ),
     );
    

【讨论】:

我可以确认,您不需要传递模型本身。你只需要在你的根页面上定义一次,然后你就可以在你的应用程序的任何地方调用它作为 ScopedModelDescendant

以上是关于Flutter / Dart 使用具有后代和 Navigator 的 Scoped Model的主要内容,如果未能解决你的问题,请参考以下文章

在 R 中使用 min() 查找最小的后代

如何使用 Angular 和 Flutter(都是 Dart)为工作区设置 VS Code 调试?

Flutter 爱之初体验

如何在 Flutter dart 的列表中的循环内附加数据?

Dart / Flutter 嵌套类静态访问

flutter Container 阴影