从 StatefulWidget 外部控制状态 [英] Controlling State from outside of a StatefulWidget
问题描述
我试图了解在 Widget 状态之外控制 StatefulWidget 状态的最佳实践.
I'm trying to understand the best practice for controlling a StatefulWidget's state outside of that Widgets State.
我定义了以下接口.
abstract class StartupView {
Stream<String> get onAppSelected;
set showActivity(bool activity);
set message(String message);
}
我想创建一个实现此接口的 StatefulWidget StartupPage
.我希望小部件执行以下操作:
I would like to create a StatefulWidget StartupPage
that implements this interface. I expect the Widget to do the following:
当一个按钮被按下时,它会通过 onAppSelected 流发送一个事件.控制器甚至会监听并执行一些操作(数据库调用、服务请求等).
When a button is pressed it would send an event over the onAppSelected stream. A controller would listen to this even and perform some action ( db call, service request etc ).
控制器可以调用 showActivity
或 set message
来让视图显示带有消息的进度.
The controller can call showActivity
or set message
to have the view show progress with a message.
因为有状态小部件不会将其状态作为属性公开,所以我不知道访问和修改状态属性的最佳方法.
Because a Stateful Widget does not expose it's State as a property, I don't know the best approach for accessing and modifying the State's attributes.
我希望使用它的方式类似于:
The way I would expect to use this would be something like:
Widget createStartupPage() {
var page = new StartupPage();
page.onAppSelected.listen((app) {
page.showActivity = true;
//Do some work
page.showActivity = false;
});
}
我曾考虑通过在 createState()
中传入我希望它返回的状态来实例化 Widget,但感觉不对.
I've thought about instantiating the Widget by passing in the state I want it to return in createState()
but that feels wrong.
为什么我们采用这种方法的一些背景:我们目前有一个 Dart Web 应用程序.为了视图控制器分离、可测试性和对 Flutter 的前瞻性思考,我们决定为应用程序中的每个视图创建一个界面.这将允许 WebComponent 或 Flutter Widget 实现此接口并保持所有控制器逻辑相同.
Some background on why we have this approach: We currently have a Dart web application. For view-controller separation, testability and forward thinking towards Flutter we decided that we would create an interface for every view in our application. This would allow a WebComponent or a Flutter Widget to implement this interface and leave all of the controller logic the same.
推荐答案
您可以使用静态方法公开状态的小部件,一些 flutter 示例就是这样做的,我也开始使用它:>
You can expose the state's widget with a static method, a few of the flutter examples do it this way and I've started using it as well:
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();
来访问状态.
You can then access the state by calling StartupPage.of(context).doSomething();
.
这里需要注意的是,您需要在其树中的某处有一个包含该页面的 BuildContext.
The caveat here is that you need to have a BuildContext with that page somewhere in its tree.
这篇关于从 StatefulWidget 外部控制状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!