[page lifecycle series] repeating Load() for view model of ModalDialog on the same PostBack

Ok, so I was wondering how long until these things start to happen… (lifecycle event shenanigans) (followed by most probably facepalms about some stupid poorly thought aspects I forgot about :slight_smile:)

I have my “form” of various fields in a ModalDialog (Popup) inside a MarkupControl2 inside MarkupControl1 inside .dothtml page with MasterPage, each with their own VM.

Now, if I select an option in any dropdown, a fetch is made to the server (and I see on the server that it is indeed just one single request),
the Popup Load() method executes 3 then consistently 4 times in a row for each PostBack.
LE: Its other 2 overrides: Init() not called at all; PreRender() executes 4 times in a row. Both Init() and PreRender() are empty because I’m not using them, just using them now for debugging.
end of LE


The Load() of the parent VM executes only once.

I have emptied the Load() of the parent VM, no code in it → same, it executes only once and the other Load() 4 times in a row.

I’ve already checked that the Popup is instantiated only in one place and that code runs only once, when the Popup is opened. Afterwards it stays open, that code is no longer touched and subsequent PostaBacks repeat this behaviour of Popup Load() running 4 times in a row.

I don’t know if it means anything useful, but the DataSource of the dropdown that triggers this is inside this:
image
that is inside this:
image
that is finally inside the VM class of the MarkupControl2:
image

This is recipe for later disaster, as I’ve already mitigated some custom events to not get overkilled with subscribers because of this.

Now, I know I may be a skippy programmer and I must thoroughly recheck my most perfectly creations but… I thought to ask, maybe anyone has some idea about this.

LE:
How do I even properly step-hop-debug this?

1 Like

I arrived here and breakpoints do not fire

I don’t know if debugging into DotVVM would help me, though.

I think the most likely reason is that you have the same view model in multiple properties. It may be at any point in the hierarchy

I think you have to disable “Just my code” setting step into lib code, but I last used VS like 7 years ago, so IDK. Then I think you should be able to step out of your Load into the function which called it.

However, you don’t need to do that, I’d just call the this.GetChildViewModels() function and check if there is the same object multiple times.

I’ve searched for it in the entire project.
In the markup is only used here:

in code-behind is instantiated only here, once, when opening popup:
image

This Open() is from the parent VM of the Popup, the one that has a Load() that runs only once.

Then I put this.GetChildViewModels(); in it:
image

And I started searching for all possible places it could get instantiated… disabling one by one…

The dumb source of the problem → my own stupid inventions, no wonder:

:clap:
:clapper:

1 Like

Hold, we’re not done yet :smile:

Although AllModals does not appear at all in the entire view model on the client-side, not in the page source, never in any of the responses to the PostBacks and this being my ticket to considering AllModals as a property (convenience), it seems to me that even though I decorate the override with Bind(Direction.None), something still goes on fishy under the covers.

:question: 1: Does DotVVM framework parse or traverse in any way these properties (like in search of VMs) even though they are marked as Bind(Direction.None) ?

Because I’ve took an alternative to the property and it does not generate duplicates of the Popup VM:

:exclamation: I need to properly understand this as to avoid future complications in other experiments / custom implementations.

Yes, we call the nested Load/Init/PreRender on all properties, regardless if they have Bind(None). The justification being that it’s usually much easier to deal with the Load being called multiple times than it not being called at all.

If you have trouble with this, note that you can override the GetChildViewModels and either check that there are no duplicates, or remove them (just call .Distinct() on it.). I’d probably stick to using methods, to make it clear which viewmodels are available client-side and which are just a proxy for some server-side code

Thank you,

Yes, I prefer to avoid the issue entirely by not using properties.