Skip to content

Instantly share code, notes, and snippets.

@JulianBissekkou
Created December 11, 2018 16:19
Show Gist options
  • Save JulianBissekkou/2368d371f6d3dc3e713bd1f8d44857b5 to your computer and use it in GitHub Desktop.
Save JulianBissekkou/2368d371f6d3dc3e713bd1f8d44857b5 to your computer and use it in GitHub Desktop.
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));
}
@alexeysmorkalov
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment