dsuryd / dotNetify

Simple, lightweight, yet powerful way to build real-time web apps.
https://dotnetify.net
Other
1.17k stars 164 forks source link

PushUpdates causes all viewmodels of same client instance to push the changes #325

Open DG4ever opened 7 months ago

DG4ever commented 7 months ago

I am using the useConnect hook to connect to different viewmodels from the same client. It seems that when I do "PushUpdates" in one of the viewmodels, the changes of both viewmodels are transmitted to the client. I dont't think this is the correct behaviour or am I doing something wrong here?

const { vm, state } = useConnect<State>(viewModelName, {},
    {
        vmArg: {
            ...initialViewModel
        },
        headers: { Origin: window.location.pathname, UrlPattern: urlPattern, UrlParams: urlParams, Authorization: "Bearer " + window.localStorage.getItem("access_token") },
        exceptionHandler: exceptionHandler
    }
);

For me this results in some problems: In one viewmodel I am using a timer to poll some data and update the view via "PushUpdates". In the other viewmodel I am calling a long operating function that fetches some data and assign it to multiple propertys of the viewmodel. Now if the "PushUpdates" of the first viewmodel is called during that function call of the second viewmodel, half of the data of the second viewmodel is pushed to the client before all data is fetched. Of course the missing data is pushed after the function is finished but in my view I expect to get all data at once.

Is this the intended behaviour of "PushUpdates" or might this be a bug?

dsuryd commented 7 months ago

Indeed, PushUpdates by design will send updates from all active view models. In your case, you may need to implement synchronization between the multiple PushUpdates, or in the long-running function, to keep the changes in a local object until you're ready to set everything to the view model properties in one go.

DG4ever commented 7 months ago

Thank you for the fast respone. I did not expect this behaviour, it seems quite counterintuitive to me (at least if the viewmodels don't interact with each other). I just looked into the VMController and all changed viewmodels also get pushed at the end of a client request:

https://github.com/dsuryd/dotNetify/blob/4d98aac878d38a941525854f0238090f3af27b3f/DotNetifyLib.Core/VMController/VMController.cs#L394-L397

https://github.com/dsuryd/dotNetify/blob/4d98aac878d38a941525854f0238090f3af27b3f/DotNetifyLib.Core/VMController/VMController.cs#L310-L313

For the active PushUpdates the corresponding code seems to be this one: https://github.com/dsuryd/dotNetify/blob/4d98aac878d38a941525854f0238090f3af27b3f/DotNetifyLib.Core/VMController/VMController.cs#L676-L680

Is there an easy way for me to override the VMController? I would like to change this behaviour.

Maybe an option to disable this behaviour and force it via a parameter in "PushUpdates" would be useful?

dsuryd commented 7 months ago

This was designed this way to ensure multiple view models stay in sync with each other. For example, in a list-detail pattern, a list selection change must also trigger the detail update. A possible solution for your use case is to add a new type of view model that the general PushUpdates would simply ignore and let it initiate its own updates in isolation, but that would require changes in a few areas of the framework, but truthfully I would rather this be solved in the application level per my previous suggestions.