1

Blazor seems aware of object changes within components without any external user intervention, for example if I have:

<p>@Data.SomeProperty</p>
<input type="text" @bind="Data.SomeProperty" />

@code {
   [Parameter]SomeModel Data {get;set;} // How do I know when this/its internals have changed?
}

Whenever the input changes it seems to understand that it needs to refresh the UI (not sure if its whole UI or just the specific parts changed). So is there a way for a developer to hook into this and be notified when something has changed?

My use case here is I want to be able to have a title field for a component (ComponentA) but the title is computed within a child component (ComponentB) so I want to be able to have ComponentB raise an event or notify in some way to indicate the computed property has changed then ComponentA can take that change and update its title.

So is there a way to be able to notify externally that the models changed WITHOUT altering the models internals? (Happy for it to be a custom EventCallback I somehow trigger as long as logic for it lives inside the component not the model)

4
  • I see nothing but EventCallback you rise when "computation" is done in ComponentB. Capture that callback and change some value in ComponentA and it will render it right away... I have to say I don't understand what you mean by "altering the models internals".. Maybe more code would help. Commented Aug 3, 2022 at 16:00
  • @Alamakanambra so I can put an EventCallback<string> in ComponentB which represents the "title has changed" event, but how do I KNOW in ComponentB that data has changed? Ultimately I want a way to be able to know inside a component if the params/properties have changed and raise an event off the back of that. Ideally in the scope of a property i.e no point raising "title changed" if some other variable changed
    – Grofit
    Commented Aug 3, 2022 at 16:26
  • 1
    You have to fire the EventCallback manually.... Well, you can fire it from the inside of a property setter... I guess you know that already. Sample would be a good way to explain all the issues. Or are you leaning towards something like NotifyPropertyChanged from Windows Desktop ? Commented Aug 3, 2022 at 17:45
  • @Alamakanambra as mentioned I cant/dont want to have to change the model in any way, I could proxy the get set for the parameter but that wouldnt indicate that Data.SomeChildProperty has changed, which is mainly what I would be wanting to listen for, current Henks answer probably seems to be closest.
    – Grofit
    Commented Aug 3, 2022 at 19:39

1 Answer 1

2

You already have [Parameter]SomeModel Data {get;set;} which is oneway communication from parent (ComponentA) to the child (ComponentB).

For the reverse direction you can use an [Parameter]EventCallback<string> OnChange { get set;}. Or use a StateManager object as a cascading value.

Your main questions seems to be

but how do I KNOW in ComponentB that data has changed?

That is easy, just use

override onParametersSet()
{
   // ... compute title 
   OnChange.InvokeAsync(title);
}

But you could easily get into a loop here, depending on how you handle this in the Parent.

4
  • Ah ok I didnt know this existed, it doesnt tell me whats changed, so I do worry that I may be firing changed events when it hasnt actually changed, but I could always potentially have some lastValue style thing to actually compare to see if its changed.
    – Grofit
    Commented Aug 3, 2022 at 19:38
  • 1
    Yes, have a look at this Q+A Commented Aug 3, 2022 at 19:44
  • Hmm I am having some limited success with this, so if I go and change the value in an input box i.e <input @bind-Value="Data.SomeTextValue"/> its not firing OnParametersSet() for some reason not if I alter a select box which is bound to the underlying data object, however if I do something on the parent it does seem to trigger the OnParameterSet method.
    – Grofit
    Commented Aug 3, 2022 at 20:41
  • 1
    I tried to explain that in the linked Answer: When CompA renders it will always render CompB to (and set the parameters) because SomeModel is 'complex'. When you have a string or bool Parameter then Blazor does 'smart updates', but here you will have to implement that logic. Commented Aug 4, 2022 at 9:03

Not the answer you're looking for? Browse other questions tagged or ask your own question.