从StatefulWidget外部控制状态 [英] Controlling State from outside of a StatefulWidget

查看:379
本文介绍了从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:

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

  1. 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 ).

控制器可以调用showActivityset 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆