MVVM Design Pattern in Flutter

后端 未结 4 1012
时光说笑
时光说笑 2021-02-06 05:26

we try to develop a flutter app and we create a stateful widget as a page .
we want to separate build function from other state variable and state function in 2 different fi

相关标签:
4条回答
  • 2021-02-06 06:07

    I suggest moving your ViewModel code into a separate class that does not extend State. Keep the ViewModel platform independent. Your Widgets state can have an instance of the viewModel and interact with it.

    You can find a more detailed example here

    If child Widgets need to access your ViewModel you can use a Inherited Widget as suggested by @Rémi Rousselet. I quickly implemented this for you:

    class ViewModelProvider extends InheritedWidget {
      final ViewModel viewModel;
    
      ViewModelProvider({Key key, @required this.viewModel, Widget child}) 
      : super(key: key, child: child);
    
      @override
      bool updateShouldNotify(InheritedWidget oldWidget) => true;
    
      static ViewModel of(BuildContext context) =>
          (context.inheritFromWidgetOfExactType(ViewModelProvider) as 
      ViewModelProvider).viewModel;
    }
    

    Child widgets can grab the ViewModel by calling

    var viewModel = ViewModelProvider.of(context);
    

    Let me know if you have any questions :)

    0 讨论(0)
  • 2021-02-06 06:16

    The mvvm package, A Flutter MVVM (Model-View-ViewModel) implementation.

    import 'package:flutter/widgets.dart';
    import 'package:mvvm/mvvm.dart';
    import 'dart:async';
    
    // ViewModel
    class Demo1ViewModel extends ViewModel {
    
      Demo1ViewModel() {
          // define bindable property
          propertyValue<String>(#time, initial: "");
          // timer
          start();
      }
    
      start() {
          Timer.periodic(const Duration(seconds: 1), (_) {
            var now = DateTime.now();
            // call setValue
            setValue<String>(#time, "${now.hour}:${now.minute}:${now.second}");
          });
      }
    }
    
    // View
    class Demo1 extends View<Demo1ViewModel> {
      Demo1() : super(Demo1ViewModel());
    
      @override
      Widget buildCore(BuildContext context) {
        return Container(
            margin: EdgeInsets.symmetric(vertical: 100),
            padding: EdgeInsets.all(40),
    
            // binding
            child: $.watchFor(#time, 
                builder: $.builder1((t) => 
                  Text(t, textDirection: TextDirection.ltr))));
      }
    }
    
    // run
    void main() => runApp(Demo1());
    

    full example

    0 讨论(0)
  • 2021-02-06 06:19

    That's not the proper approach. You shouldn't split State<T> and it's build method. The thing is, don't extend widgets. Compose them.

    A correct way to achieve something similar is to use InheritedWidget. These will hold you data but do nothing else. And it's children will be able to request those datas using a MyInherited.of(context).

    You could also create a builder. Something like :

    typedef Widget MyStateBuilder(BuildContext context, MyStateState state);
    
    class MyState extends StatefulWidget {
      final MyStateState builder;
    
      const MyState({this.builder}) : assert(builder != null);
    
      @override
      MyStateState createState() => new MyStateState();
    }
    
    class MyStateState extends State<MyState> {
      String name;
    
      @override
      Widget build(BuildContext context) {
        return widget.builder(context, this);
      }
    }
    
    0 讨论(0)
  • 2021-02-06 06:19

    I have been using this plugin maintaining large scale application for flutter.mvvm_flutter

     https://pub.dev/packages/mvvm_flutter
    

    it's very light and easy to use check some example . its very easy to maintain ui away from business logic's

    0 讨论(0)
提交回复
热议问题