Skip to content

Commit ab1cd51

Browse files
authored
Refactor ViewModel change subscriptions in Blazor components (#4069)
<!-- Please be sure to read the [Contribute](https://github.com/reactiveui/reactiveui#contribute) section of the README --> **What kind of change does this PR introduce?** <!-- Bug fix, feature, docs update, ... --> Bug Fix for #4068 **What is the current behavior?** <!-- You can also link to an open issue here. --> #4068 **What is the new behavior?** <!-- If this is a feature change --> Consolidated and streamlined the logic for subscribing to ViewModel changes and property changes in ReactiveComponentBase, ReactiveInjectableComponentBase, and ReactiveLayoutComponentBase. This improves code readability and consistency across the components by using a shared pattern for handling ViewModel and property change notifications. Closes #4068 **What might this PR break?** None expected **Please check if the PR fulfills these requirements** - [ ] Tests for the changes have been added (for bug fixes / features) - [ ] Docs have been added / updated (for bug fixes / features) **Other information**:
1 parent d352cd6 commit ab1cd51

File tree

3 files changed

+42
-36
lines changed

3 files changed

+42
-36
lines changed

src/ReactiveUI.Blazor/ReactiveComponentBase.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ protected override void OnAfterRender(bool firstRender)
9797

9898
viewModelChanged
9999
.Select(x =>
100-
Observable
101-
.FromEvent<PropertyChangedEventHandler?, Unit>(
102-
eventHandler =>
103-
{
104-
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
105-
return Handler;
106-
},
107-
eh => x.PropertyChanged += eh,
108-
eh => x.PropertyChanged -= eh))
100+
Observable
101+
.FromEvent<PropertyChangedEventHandler?, Unit>(
102+
eventHandler =>
103+
{
104+
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
105+
return Handler;
106+
},
107+
eh => x.PropertyChanged += eh,
108+
eh => x.PropertyChanged -= eh))
109109
.Switch()
110110
.Subscribe(_ => InvokeAsync(StateHasChanged))
111111
.DisposeWith(_compositeDisposable);

src/ReactiveUI.Blazor/ReactiveInjectableComponentBase.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ protected override void OnAfterRender(bool firstRender)
9898

9999
viewModelChanged
100100
.Select(x =>
101-
Observable
102-
.FromEvent<PropertyChangedEventHandler, Unit>(
103-
eventHandler =>
104-
{
105-
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
106-
return Handler;
107-
},
108-
eh => x.PropertyChanged += eh,
109-
eh => x.PropertyChanged -= eh))
101+
Observable
102+
.FromEvent<PropertyChangedEventHandler, Unit>(
103+
eventHandler =>
104+
{
105+
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
106+
return Handler;
107+
},
108+
eh => x.PropertyChanged += eh,
109+
eh => x.PropertyChanged -= eh))
110110
.Switch()
111111
.Subscribe(_ => InvokeAsync(StateHasChanged))
112112
.DisposeWith(_compositeDisposable);

src/ReactiveUI.Blazor/ReactiveLayoutComponentBase.cs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,34 +84,40 @@ protected override void OnAfterRender(bool isFirstRender)
8484
{
8585
if (isFirstRender)
8686
{
87-
this.WhenAnyValue(x => x.ViewModel)
88-
.Skip(1)
89-
.WhereNotNull()
87+
var viewModelChanged =
88+
this.WhenAnyValue(x => x.ViewModel)
89+
.WhereNotNull()
90+
.Publish()
91+
.RefCount(2);
92+
93+
viewModelChanged
94+
.Subscribe(_ => InvokeAsync(StateHasChanged))
95+
.DisposeWith(_compositeDisposable);
96+
97+
viewModelChanged
98+
.Select(x =>
99+
Observable
100+
.FromEvent<PropertyChangedEventHandler, Unit>(
101+
eventHandler =>
102+
{
103+
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
104+
return Handler;
105+
},
106+
eh => x.PropertyChanged += eh,
107+
eh => x.PropertyChanged -= eh))
108+
.Switch()
90109
.Subscribe(_ => InvokeAsync(StateHasChanged))
91110
.DisposeWith(_compositeDisposable);
92111
}
93112

94-
this.WhenAnyValue(x => x.ViewModel)
95-
.WhereNotNull()
96-
.Select(x => Observable.FromEvent<PropertyChangedEventHandler, Unit>(
97-
eventHandler =>
98-
{
99-
void Handler(object? sender, PropertyChangedEventArgs e) => eventHandler(Unit.Default);
100-
return Handler;
101-
},
102-
eh => x.PropertyChanged += eh,
103-
eh => x.PropertyChanged -= eh))
104-
.Switch()
105-
.Do(_ => InvokeAsync(StateHasChanged))
106-
.Subscribe()
107-
.DisposeWith(_compositeDisposable);
113+
base.OnAfterRender(isFirstRender);
108114
}
109115

110116
/// <summary>
111117
/// Invokes the property changed event.
112118
/// </summary>
113119
/// <param name="propertyName">The name of the property.</param>
114-
protected virtual void OnPropertyChanged([CallerMemberName]string? propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
120+
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
115121

116122
/// <summary>
117123
/// Cleans up the managed resources of the object.

0 commit comments

Comments
 (0)