从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.
推荐答案
您可以使用静态方法公开状态窗口小部件,一些颤动的示例以这种方式进行操作,并且我也开始使用它:>
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屋!