Our state of the art Gantt chart


Post by Jerther »

Hi!!

I'm migrating from 2.1.7 to 4.1.4. Easier than I thought (yet), thanks for the very helpful upgrade guides.

I'm having difficulty migrating one part about destroying though. Let's start with this line:

old code:
this.bryntumGantt.BryntumWidgetAdapterRegister.register(ColorField.type, ColorField);

Which is easily migrated to:

New code:
ColorField.initClass();

My app is pretty big so I unload the Gantt diagram when it's not needed with:

this.gantt.destroy();

Now I think I need to destroy the widget factory as well because when I return to the Gantt diagram part of my app, I get:

Type "colorfield" already registered with Widget factory

I could force the re-register but I'd rather keep memory usage low and destroy the factory when it's not needed.

So, is there a way to unload/destroy the Widget factory like I do with the Gantt diagram?


Post by mats »

Great to hear you had a pleasant upgrade experience. Classes should just be defined once so it's not really valid to try to destroy the WidgetFactory in our current code base. Its memory footprint should also be microscopic and not worth cleaning up.

Gantt destroy should be good enough and should release all data and memory consuming objects (if it doesn't please let us know, then we have a leak).


Post by Jerther »

Thanks mats.

I just realized the initClass() method has no "replace" parameter. I was thinking of the register() method which is part of the class initialization.

The framework I'm using expects all the parts of my app to be properly destroyed when the user leaves them. I think I might still be fine with leaving the WidgetFactory loaded but I can't find how to check if my class is already registered before calling initClass(), and I'd rather not have a global variable to try to keep track ;)

Do you have a suggestion?


Post by saki »

My app is pretty big so I unload the Gantt diagram when it's not needed with:

this.gantt.destroy();

This is the correct way to do it. It destroys the instance of the Gantt class, not the class itself. It looks like you are trying to load classes 2nd time what is not needed. Memory freed by destroying the instance should be enough.

Note: The "old way" just didn't tell you that the class was already registered so it seemed to work.


Post by Jerther »

Hi saki,

Yes the gantt.destroy() part works fine. Well, if it can clarify the matter, let me give you some more context:

  • Every time a user enters the gantt section of the app, the framework calls an init() function. In there, I initialize the Gantt instance and my classes.
  • When the user leaves that section (or goes elsewhere in the app), the framework calls a destroy() function. In there, I destroy the Gantt instance and release everything that's been assigned in the init() function.

The problem I'm having is that when the user enters, then leaves, then comes back again, I get the error because, you are right, my code doesn't do any check and tries to load my classes a 2nd time. But how do I know they've already been loaded?

I could do something like:

init() {
  if (!window.bryntumClassesAreLoaded) {
    MyClass.initClass();
    window.bryntumClassesAreLoaded = true;
  }
}

But that feels a bit hackish and I'd rather not use window variables for that purpose. I'd rather follow the framework's guidelines and do something like this:

destroy() {
  MyClass.destroyClass();  // or WidgetFactory.destroy() or something that [i]undoes[/i] initClass()
}

But given that I can't, I could do with something like this:

init() {
  if (!MyClass.isInitialized) {
    MyClass.initClass();
  }
}

Of course isInitialized does not exist but is there a way to do a similar check before calling initClass() ?


Post by Jerther »

For now I've come up with this workaround but I wouldn't count on it for long:

class TagsField extends this.bryntumGantt.Combo {
    static get classIsInitialized() {
        const { caseless, registry } = this.factoryable;
        const key = caseless ? this.name.toLowerCase() : this.name;
        return key in registry;
    }
if (!TagsField.classIsInitialized)
    TagsField.initClass();

Post by johan.isaksson »

Hi,

There is a private static fn resolveType() on factories to resolve a registered class by name. Using it should allow you to detect if a class is registered already or not:

if (!Widget.resolveType('mytype', true)) {

}

Second arg is to prevent it from throwing when type is not registered.

Will discuss with the team if we can make the function public.

Best regards,
Johan Isaksson

Post by Jerther »

Thanks Johan, this works well. I hope the method becomes public so I don't get any surprise later ;)


Post by Jerther »

Hi Johan!

Any chance of resolveType becoming public soon? ;)


Post by johan.isaksson »

Hello,

Fair question, I'll make it public for next patch release

Best regards,
Johan Isaksson

Post Reply