Kendo - can two Observable objects use the "change" event on the same page?

351 views Asked by At

I have a page that uses a Kendo MVVM approach for two different elements, one providing file search results, the other a document upload facility.

The problem I am encountering is to do with the change event that both elements use - it seems that when one control fires a change event it is then picked up by the other control, which then attempts to process the event and passes it on, at which point it is picked up by the second control's change handler which processes it and passes it on to the first control's change handler. As you might expect, after around 1500 repetitions of this cycle, I see a Uncaught RangeError: Maximum call stack size exceeded message as the JavaScript engine runs out of memory.

At first I thought the problem was that the container of the second model was contained within the first, but even if they are completely separate on the page it seems as though the problem still shows up, so now I'm wondering whether the problem is related to the event being global to the page.

It seems that anything I do in my event handler in terms of trying to stopPropagation or stopImmediatePropagation - or even to set the event to null altogether - makes no difference to this behaviour. Tracing the call stack I can see it looping through Kendo's trigger call then through the event binding on my object and jQuery's dispatch loops that lead it back to Kendo, where it triggers the event handler on the other observable object.

Removing my bindings does not affect the problem, the change event is still bounced back and forth between Kendo and jQuery in the same way, it just doesn't run through my code.

1

There are 1 answers

0
glenatron On

The answer here was not a direct consequence of Kendo itself, so it would have been hard to answer from the question as I set it.

Inside the Observable container that was raising this error, I was using Isotope for layout. The step I had missed was that I had a relationship like this:

 Parent [Observable] 
    -> Container 
        -> Child 
        -> Child
        -> Child

One of the things that Isotope brings to the party is that for each item in the child collection, it adds a reference to its parent object.

When the child is Observable that creates a structure like this:

 Parent [Observable] 
    -> Container <--┐
        -> Child ---|
        -> Child ---|
        -> Child ---┘

This is an ideal situation for events to be propagated from child to parent, but because the properties in question were being automagically added by the libraries in question it was very hard to troubleshoot.

The solution was to remove the Container layer from the Observable model - it didn't need to trigger anything on change and so I wrapped it in a simple getContainer() closure and used that everywhere I was previously using it as a property. This protected it from the Observable object, breaking the circular reference without harming the functionality.

It may also be relevant that as far as I can tell the initiating event was a DOM change event rather than one of Kendo's own events. The problem may have been avoidable by using a custom Kendo namespace but that would have been a significant change in a complex application and guaranteed to cause a lot of side effects.