Closed GIfatahTH closed 2 years ago
Amazing! Now it's easier to deal with the MVVM.
Thats truly an MVVM approach which amazes me too
@xalikoutis @amoslai5128 Thanks for the comments. I want to know what you mean by truly an MVVM? I want to learn from you.
I want to learn also, please do explain
Before flutter i was a Xamarin Dev. Xamarin uses MVVM pattern in order to separate your business logic from the UI. It consists from
you can bind your ViewModel properties and commands to the UI, like you also do in angular and vuejs, and notify the view of any state changes through change notification events. This binding is 2 way back and forth.
The ReactiveWidget
works in a similar way as a handler for change notification events in the ViewModel(CounterModel).
So @GIfatahTH i believe we are closer as we can get to MVVM pattern which i really love for its simplicity
The upcoming update, OnReactive()
, looks so clean in the UI layer, this beautiful combination is the second time I've seen ever in Flutter, since Stacked
with its architecture.
I think MVVM's kind is a lightweight version of Clean Architecture Design, and very friendly to small project, the scope is trying to separate the logic out between the UI and services, data source layer by setting up a ViewModel as a bridge. Therefore, the UI code would look good to get maintenance.
If somebody had experience in VueJs would probably know, and sadly I cannot find updated article for flutter, even though the widget style is very suitable for it.
Here is another improvement:
If you want a widget and all its child to rebuild in response to state mutation, just use ReactiveStatelessWidget
instead of StatelessWidget
for the parent widget.
class CounterModel {
final counter1 = RM.inject(()=> 0) // Or just use extension: 0.inj()
final counter2 = 0.inj();
int get sum => counter1.state + counter2.state;
void increment1() => counter1.state++;
void increment2() => counter2.state++;
void asyncMethod() => counter1.setState((s) async => asyncRep())
}
final counterModel = CounterModel();
///Use ReactiveStatelessWidget instead of StatelessWidget
class MyParentWidget extends ReactiveStatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
_Widget1(),
_Widget2(),
_Widget3(),
],
);
}
}
class _Widget1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('${counterModel.counter1.state}');
}
}
class _Widget2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('${counterModel.counter2.state}');
}
}
class _Widget3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('${counterModel.sum}');
}
}
@GIfatahTH you nailed it
@GIfatahTH Can't wait for the update!
Referring to issue #205 , I get out with a new widget; The
OnReactive
OnReactive
widget is a new widget used to rebuild a part of the widget tree in response to state change.OnReactive
implicitly subscribes to injected ReactiveModels based on the getterReactiveModel.state
called during rebuild.Example:
Note that counter1 and counter2 are global final variable that holds the state. They are disposed automatically when not in use (have no listener).
You can scope the counter1 and counter2 variable and put them inside a class:
OnReactive
can listen to any state called form its child widget tree, no matter how deep the widget tree is.Inside
OnReactive
you can call any of the available state status flags (isWaiting, hasError, hasData, ...) or just use onAll and onOr methods:OnReactive
is a lightweight widget that behaves as it is a const widget. That is, onceOnReactive
is created, it will not recreate after parent widgets rebuild.OnReactive
is rebuild only after any observable state emits a notification or after hot restart.This is the full API of
OnReactive
:Try is using the published dev version.
UPDATE
If you want a widget and all its child to rebuild in response to state mutation, just use
ReactiveStatelessWidget
instead ofStatelessWidget
for the parent widget.