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

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

推荐答案

您可以使用静态方法公开状态的小部件,一些 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屋!

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