2017-09-05 36 views
0

我想了解控制状态窗口状态之外的StatefulWidget状态的最佳做法。从状态控件外部控制状态

我有下面的接口定义。

abstract class StartupView { 
    Stream<String> get onAppSelected; 

    set showActivity(bool activity); 
    set message(String message); 
} 

我想创建一个实现此接口的StatefulWidget StartupPage。我期望Widget执行以下操作:

  1. 当按下按钮时,它会通过onAppSelected流发送事件。一个控制器甚至可以监听它并执行一些操作(数据库调用,服务请求等)。

  2. 控制器可以调用showActivityset message使视图显示消息的进度。

因为有状态的Widget不公开是国家作为一个属性,我不知道用于访问和修改国家的属性的最佳方法。

我希望用这种方式会是这样的:

Widget createStartupPage() { 
    var page = new StartupPage(); 
    page.onAppSelected.listen((app) { 
     page.showActivity = true; 
     //Do some work 
     page.showActivity = false; 
    }); 
    } 

我想过通过传递,我希望它在createState()返回状态实例化组件,但是,感觉错了。

为什么我们有这种方法的一些背景:我们目前有一个Dart web应用程序。对于视图控制器分离,可测试性和对Flutter的前瞻性思考,我们决定为应用程序中的每个视图创建一个接口。这将允许WebComponent或Flutter Widget实现此接口并保持所有控制器逻辑相同。

回答

2

您可以用静态方法,几扑例子做这种方式,我已经开始使用它,以及暴露状态的小工具:

class StartupPage extends StatefulWidget { 
    static _StartupPageState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<_StartupPageState>()); 

    @override 
    _StartupPageState createState() => new _StartupPageState(); 
} 

class _StartupPageState extends State<StartupPage> { 
    ... 
} 

然后,您可以通过调用访问状态StartupPage.of(context).doSomething();

这里需要注意的是,你需要在树的某个地方有一个BuildContext。

+0

如果这是一个合理的解决方案,让StatefulWidget将它的状态存储在属性中是否也是合理的? –

+0

问题在于'createState()'是一个由flutter调用的生命周期方法,所以你不应该自己调用它并存储返回的状态。 – xqwzts

+0

我用这种方法看到的问题是,它需要我们的通用控制器成为Widget树的一部分,这将违背我们的设计目标,让它们在Web上可重用。似乎Flutter强迫任何需要将小部件的状态改变为小部件本身的东西。 –