view_model 0.5.0-dev.12
view_model: ^0.5.0-dev.12 copied to clipboard
view model for flutter. Simple and Lightweight & Cross - Widget Sharing & Automatic Resource Disposal
0.5.0 #
- Breaking Change & API Refinement: Major overhaul of ViewModel access
methods to clarify responsibilities and improve predictability.
watchViewModel
/readViewModel
:- Now primarily responsible for creating new ViewModel instances.
- The
factory
parameter is now mandatory. - Behavior depends on the provided
factory
:- If the
factory
includes akey
, the instance is created and cached (or retrieved if already cached). - If the
factory
has nokey
, a new, non-shared instance is created every time.
- If the
- New Methods for Cached Access:
- Introduced
watchCachedViewModel
andreadCachedViewModel
to explicitly find existing, cached ViewModel instances bykey
ortag
. - Introduced
maybeWatchCachedViewModel
andmaybeReadCachedViewModel
for safely accessing cached instances without throwing errors if not found.
- Introduced
- Migration Guide:
- To create/watch a new instance: Continue using
watchViewModel
but you must provide afactory
. - To find an existing instance: Replace
watchViewModel(key: ...)
withwatchCachedViewModel(key: ...)
orreadCachedViewModel(key: ...)
.
- To create/watch a new instance: Continue using
- support ViewModel-to-ViewModel Access
- Breaking change: The
key
parameter inwatchViewModel
,readViewModel
, andViewModel.read
has been changed fromString?
toObject?
. This allows for the use of custom objects as keys, but requires proper implementation of==
andhashCode
for custom key objects.
ViewModels can access other ViewModels using readViewModel
and watchViewModel
:
readViewModel
: Access another ViewModel without reactive connectionwatchViewModel
: Create reactive dependency - automatically notifies when the watched ViewModel changes
When a ViewModel (the HostVM ) accesses another ViewModel (the SubVM ) via watchViewModel , the framework automatically binds the SubVM 's lifecycle to the HostVM 's UI observer (i.e., the State object of the StatefulWidget ).
This means both the SubVM and the HostVM are directly managed by the lifecycle of the same State object. When this State object is disposed, if neither the SubVM nor the HostVM has other observers, they will be disposed of together automatically.
This mechanism ensures clear dependency relationships between ViewModels and enables efficient, automatic resource management.
class UserProfileViewModel extends ViewModel {
void loadData() {
// One-time access without listening
final authVM = watchCachedViewModel<AuthViewModel>();
if (authVM?.isLoggedIn == true) {
_fetchProfile(authVM!.userId);
}
}
void setupReactiveAuth() {
// Reactive access - auto-updates when auth changes
final authVM = watchCachedViewModel<AuthViewModel>();
// This ViewModel will be notified when authVM changes
}
void manualListening() {
final authVM = watchCachedViewModel<AuthViewModel>();
// You can also manually listen to any ViewModel
authVM?.listen(() {
// Custom listener logic
_handleAuthChange(authVM);
});
}
}
0.4.7 #
- fix
ViewModel.read
0.4.6 #
- The
view_model
package includes a powerful DevTools extension that provides real-time monitoring and debugging capabilities for your ViewModels during development. - create
devtools_options.yaml
in root directory of project.
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
- view_model: true
- Breaking change: rename
initConfig
toinitialize
0.4.5 #
- Add
DefaultViewModelFactory
for convenient and generic ViewModel factory creation.
0.4.4 #
- Add
ViewModel.maybeRead
0.4.3 #
- Add
maybeWatchViewModel
andmaybeReadViewModel
- update
watchViewModel
find logic
VM watchViewModel<VM extends ViewModel>({
ViewModelFactory<VM>? factory,
Object? key,
Object? tag,
});
Parameter Name | Type | Optional | Description |
---|---|---|---|
factory |
ViewModelFactory<VM>? |
✅ | Provides the construction method for the ViewModel. Optional; if an |
existing instance is not found in the cache, it will be used to create a new | |||
one. | |||
key |
String? |
✅ | Specifies a unique key to support sharing the same ViewModel instance. |
First, it tries to find an instance with the same key in the cache. | |||
tag |
Object? |
✅ | Add a tag for ViewModel instance. get tag by viewModel.tag . and it's |
used by find ViewModel by watchViewModel(tag:tag) . |
🔍 Lookup Logic Priority (Important)
The internal lookup and creation logic of watchViewModel
is as follows
(executed in priority order):
- If a key is passed in:
- First, attempt to find an instance with the same key in the cache.
- If a factory exists, use the factory to get a new instance.
- If no factory is found and no instance is found, an error will be thrown.
- If a tag is passed in, attempt to find the latest created instance which has the same tag in the cache.
- If nothing passed in, attempt to find the latest created instance of this type in the cache.
⚠️ If no ViewModel instance of the specified type is found, an error will be thrown. Ensure that the ViewModel has been correctly created and registered before use.
0.4.2 #
- Support find existing ViewModel by tag
set tag in ViewModelFactory.getTag()
:
class MyViewModelFactory extends ViewModelFactory<MyViewModel> {
@override
Object? getTag() {
return 'tag';
}
}
find existing ViewModel by tag:
late final MyViewModel viewModel;
@override
void initState() {
super.initState();
viewModel = watchViewModel<MyViewModel>(tag: 'tag');
}
0.4.1 #
Breaking change:
- Use
recycleViewModel
instead ofrefreshViewModel
.
0.4.0 #
Breaking change:
-
Use
ViewModel
instead ofStatelessViewModel
. -
Use
StateViewModel
instead ofViewModel
. -
Use either
watchViewModel
orreadViewModel
instead ofgetViewModel
/requireExistingViewModel
. -
Use
StateViewModel.listenState
instead ofViewModel.listen
. -
Use
ViewModel.listen
instead ofViewModel.addListener
. -
Support
ViewModel.read<T>
to read existing view model globally.
0.3.0 #
- transfer to https://github.com/lwj1994/flutter_view_model. thank to Miolin