-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug 🐞
When deriving my Page (view) from ReactiveInjectableComponentBase
and providing a view model class that implements IActivatableViewModel
, my callback provided to this.WhenActivated()
is not invoked for me.
Step to reproduce
-
Derive your page from the mentioned base class like so:
@inherits ReactiveInjectableComponentBase<MonitorDeploymentsViewModel>
-
Implement your view model like this:
public class MonitorDeploymentsViewModel : ReactiveObject, IActivatableViewModel
-
Provide a call to
WhenActivated
like so:this.WhenActivated(disposal => { // Do something meaningful here });
-
Compile and run the application. Be sure to visit the page we're talking about to trigger the issue.
Reproduction repository
This is a non-public repository; I have no MCVE.
Expected behavior
The ReactiveInjectableComponentBase
class (as well as the other Blazor-specific component base classes) implement ICanActivate
and already trigger the following:
- When
OnInitializedAsync()
is invoked by the view, trigger Activated state. - When
Dispose()
happens (IDisposable
), trigger Deactivated state.
However, by default, there are no observers for these states. This is because, in my opinion, in the setter for ReactiveInjectableComponentBase.ViewModel
, code is missing to check if the supplied VM implements IActivatableViewModel
and if so, attaches it to the appropriate Activated/Deactivated observables.
The workaround right now requires users to manually override OnInitializedAsync()
simply to invoke ViewModel.Activator.Activate()
, as well as the corresponding Dispose() override for the Deactivate(). This means that, ultimately, there's logic in the ComponentBase class that ends up not getting used at all because it's not tied in.
I think the addition necessary to the base ViewModel
property is as follows:
_viewModel = value;
if (_viewModel is IActivatableViewModel avm)
{
Activated.Subscribe(_ => avm.Activator.Activate());
Deactivated.Subscribe(_ => avm.Activator.Deactivate());
}
Another solution I tested that seems to work:
protected override void OnInitialized()
{
Activated.Subscribe(_ => ViewModel!.Activator.Activate());
Deactivated.Subscribe(_ => ViewModel!.Activator.Deactivate());
base.OnInitialized();
}
Screenshots 🖼️
No response
IDE
Rider Windows
Operating system
Windows
Version
10
Device
N/A
ReactiveUI Version
18.3.1
Additional information ℹ️
I created this issue at the request of @glennawatson, who discussed this with me in Slack.