Flutter 中的 UI 和逻辑分离

S D*_*Das 4 user-interface logic widget flutter

通常,我使用一个单独的类,并在小部件顶部声明一个对象。我想知道该架构有什么问题。

我在 Flutter 中遇到了一个完整的包,WidgetView,它需要声明一个依赖项,然后创建一个状态对象,然后做同样的事情。

为什么不只是一个简单的类来实现相同的目标呢?像下面这样

class NewAccountComponent extends StatelessWidget {  
final NewAccountComponentLogic logic = NewAccountComponentLogic();
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Enter a Unique Account Number'),
      titlePadding: EdgeInsets.all(20.0),
      content: TextFormField(
        controller: logic.controller,
            onPressed: () => logic.clearTextFormField(),
          ),
        ),
}
class NewAccountComponentLogic {
  static String accountNumber;
  static bool existsAccountNumber;
  TextEditingController controller = TextEditingController();
  clearTextFormField() {
    controller.text = '';
    accountNumber = '';
}
Run Code Online (Sandbox Code Playgroud)

Ign*_*ior 9

您可以通过多种方式分离小部件逻辑和表示。我见过(并且您提到过)的一种是使用 WidgetView 模式。您可以在没有任何依赖的情况下执行此操作:

\n
    \n
  1. 创建一个抽象类,其中包含所有 WidgetView 都应实现的逻辑:
  2. \n
\n

对于无状态小部件:

\n
abstract class StatelessView<T1> extends StatelessWidget {\n  final T1 widget;\n  const StatelessView(this.widget, {Key key}) : super(key: key);\n  \n  @override\n  Widget build(BuildContext context);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

对于有状态小部件:

\n
abstract class WidgetView<T1, T2> extends StatelessWidget {\n  final T2 state;\n  T1 get widget => (state as State).widget as T1;\n\n  const WidgetView(this.state, {Key key}) : super(key: key);\n  \n  @override\n  Widget build(BuildContext context);\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 正常创建你的小部件:
  2. \n
\n
// Note it\'s a StatefulWidget because accountNumber mutates\nclass NewAccountComponent extends StatefulWidget {\n  @override\n  _NewAccountComponentState createState() => _NewAccountComponentState();\n}\n\nclass _NewAccountComponentState extends State<NewAccountComponent> {\n  String accountNumber;\n  bool existsAccountNumber;\n  final TextEditingController controller = TextEditingController();\n\n  clearTextFormField() {\n    controller.text = \'\';\n    accountNumber = \'\';\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return AlertDialog(\n      title: Text(\'Enter a Unique Account Number\'),\n      titlePadding: EdgeInsets.all(20.0),\n      content: TextFormField(\n        controller: controller,\n        onSaved: (value) => clearTextFormField(),\n      ),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 如果小部件是Stateful
  2. \n
\n
class NewAccountComponent extends StatefulWidget {\n  @override\n  _NewAccountComponentController createState() => _NewAccountComponentController();\n}\n\n// State suffix renamed to Controller\n// This class has all widget logic\nclass _NewAccountComponentController extends State<NewAccountComponent> {\n  String accountNumber;\n  bool existsAccountNumber;\n  final TextEditingController controller = TextEditingController();\n\n  clearTextFormField() {\n    controller.text = \'\';\n    accountNumber = \'\';\n  }\n\n  // In build, returns a new instance of your view, sending the current state\n  @override\n  Widget build(BuildContext context) => _NewAccountComponentView(this);\n}\n\n// View extends of WidgetView and has a current state to access widget logic\n// with widget you can access to StatefulWidget parent\nclass _NewAccountComponentView\n    extends WidgetView<NewAccountComponent, _NewAccountComponentController> {\n\n  _NewAccountComponentView(_NewAccountComponentController state): super(state);\n\n  @override\n  Widget build(BuildContext context) {\n    return AlertDialog(\n      title: Text(\'Enter a Unique Account Number\'),\n      titlePadding: EdgeInsets.all(20.0),\n      content: TextFormField(\n        controller: state.controller,\n        onSaved: (value) => state.clearTextFormField(),\n      ),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
    \n
  1. 如果是无状态的,则更改为:
  2. \n
\n
class MyStatelessWidget extends StatelessWidget {\n  final String textContent = "Hello!";\n\n  const MyStatelessWidget({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      child: Text(textContent),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

到:

\n
// Widget and logic controller are unit\nclass MyStatelessWidget extends StatelessWidget {\n  final String textContent = "Hello!";\n\n  const MyStatelessWidget({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) => _MyStatelessView(this);\n}\n\n// The view is separately\nclass _MyStatelessView extends StatelessView<MyStatelessWidget> {\n  _MyStatelessView(MyStatelessWidget widget) : super(widget);\n\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      child: Text(widget.textContent),\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

参考:

\n

Flutter:WidgetView \xe2\x80\x94 布局和逻辑的简单分离

\n