Created
December 11, 2018 16:19
-
-
Save JulianBissekkou/2368d371f6d3dc3e713bd1f8d44857b5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef Widget EmptyBuilder(); | |
typedef Widget Builder<T>(T state); | |
typedef R Mapper<R, S>(S state); | |
typedef void Handler<T>(T event); | |
abstract class ViewModelWidgetState<W extends StatefulWidget, | |
S extends Cloneable<S>, VM extends StateViewModel<S>> extends State<W> { | |
final List<StreamSubscription> _subscriptionsList = | |
List<StreamSubscription>(); | |
List<DistinctStateNotifier> _stateNotifiers = List(); | |
S _state; | |
Injector get injector => Injector(); | |
VM _viewModel; | |
VM get viewModel { | |
if (_viewModel == null) | |
throw Exception("ViewModel was not created or is already disposed!"); | |
return _viewModel; | |
} | |
VM createViewModel(); | |
@override | |
void initState() { | |
_viewModel = createViewModel(); | |
if (_viewModel == null) { | |
throw Exception("The viewmodel from type \"$VM\" is null"); | |
} | |
//immediately set the initial state to avoid ui glitches | |
//cause by the async delivery of states | |
setState(() => _state = _viewModel.initialState); | |
super.initState(); | |
_subscriptionsList.add(_viewModel.state.listen((state) { | |
setState(() => _state = state); | |
_onStateChanged(_state); | |
})); | |
afterViewModelInit(); | |
} | |
Widget buildState(S state); | |
Widget buildLoading() => Container(); | |
@override | |
Widget build(BuildContext context) { | |
if (_state != null) return buildState(_state); | |
return buildLoading(); | |
} | |
/** | |
* Called after the initState - Can ensure that the VM is successfully created | |
*/ | |
void afterViewModelInit() {} | |
@override | |
void dispose() { | |
_subscriptionsList.forEach((subscription) => subscription?.cancel()); | |
_viewModel.dispose(); | |
_viewModel = null; | |
super.dispose(); | |
} | |
void _onStateChanged(S state) => | |
_stateNotifiers.forEach((notifier) => notifier.onNewState(state)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
hi, how would you do navigation in MVVM? I mean View knows context, but it is model that must decide there and when to go... Thanks.