Interview with Atanas Popov

I started this blog because I wanted to learn ExtJS better and I tend to grasp things easier if I write them out twice (once in my codebase, then again on this blog). I cannot believe it was 7 years ago. My son is now 9 years old. What part of my life have I given to this technology, instead of him?

I’ve been writing less and less because I feel like I’ve grasped ExtJS to a deep enough extent for my purpose. Maintaining this WordPress blog has become a pain, so any further writing I will continue via the Medium platform.

This is the last post I will make on this blog. I invite you to read interview I did yesterday with Sencha’s new GM:

https://medium.com/@IvanJouikov/state-of-sencha-interview-with-atanas-popov-f80f3dde770e

VN:F [1.9.22_1171]
Rating: 10.0/10 (3 votes cast)

5 ExtJS6 Internal Caches

I’ve recently been involved in some memory leak troubleshooting and wanted to note the following caches, which often end up being the culprits retainers of some objects that were not cleaned up (e.g. destroy()) correctly, for one reason or another:

Ext.ComponentManager.all   // Ext.Component cache as map
Ext.cache                  // Ext.Element cache as map
Ext.StoreManager.items     // Ext.data.Store cache as array
Ext.fx.Manager.targets.map // Ext.fx.target.Element cache as map
Ext.dd.DragDropManager.ids // DD Object cache as map - also "leaks" by design;
                           // it retains empty objects mapped out to IDs that
                           // used to be legit components, so minimal memory
                           // impact, but those IDs are never wiped

I also would like to share the following functions that I use to compare snapshots of these caches:

// e.g.
// * var s1 = getCacheSnapshot()
// * ... interact with the app
// * var s2 = getCacheSnapshot()
// * compareCacheSnapshots(s1, s2);
function getCacheSnapshot() {
    return {
        cmp: Ext.Object.getKeys(Ext.ComponentManager.all),
        el: Ext.Object.getKeys(Ext.cache),
        st: Ext.Array.pluck(Ext.StoreManager.items, 'storeId'),
        fx: Ext.Object.getKeys(Ext.fx.Manager.targets.map),
        dd: Ext.Object.getKeys(Ext.dd.DragDropManager.ids)
    };
}
 
// logs any deltas
function compareCacheSnapshots(s1, s2) {
    function diffArrays(name, a1, a2) {
        var added = Ext.Array.difference(a2, a1);
        var removed = Ext.Array.difference(a1, a2);
        if (added.length || removed.length) {
            console.log(' ---- ', name, 'Added:', added, 'Removed:', removed);
        }
    }
    for (var key in s1) {
        var a1 = s1[key];
        var a2 = s2[key];
        console.log(key, a1.length === a2.length ? a1.length : a1.length + '->' + a2.length);
        diffArrays(key, a1, a2);
    }
}
VN:F [1.9.22_1171]
Rating: 5.1/10 (18 votes cast)

Implicit ViewModel 2-Way Data Bindings

I’ve come across a rather interesting… let’s call it “feature” of ExtJS ViewModel and data binding system. Turns out it is possible to establish “implicit” two-way data binds between parent & child view model data (within same component hierarchy) by setting the data of “lower” view model to “undefined”, so long as the view models both define that data property with the same name. Picture the following simple hierarchy:

  • Parent Panel

    • Child Panel

Now imagine that both of the panels define their own ViewModels (implicit or not doesn’t matter) that both define the same two properties, like so:

  • Parent Panel

    • undefinedText: “default Parent text”
    • definedText: “default Parent text”
  • Child Panel

    • undefinedText: undefined
    • definedText: “default Child text”

This is what the default rendering of these panels would look like:
Screen

Read on for a walk through of various scenarios and a Sencha Fiddle…
Continue reading Implicit ViewModel 2-Way Data Bindings

VN:F [1.9.22_1171]
Rating: 6.0/10 (21 votes cast)

Declarative Listeners vs. Control

Back in ExtJS 5 Sencha rolled out a rather cool concept of declarative listeners, where you could write something like this:

{
    xtype: 'button',
    handler: 'onButtonClick'
}

…note that onButtonClick is a string, rather than a function reference. The idea here is that the actual function would be resolved at runtime and will be located somewhere in the ViewController world. It was described well by Don Griffin in his blog post: https://www.sencha.com/blog/using-viewcontrollers-in-ext-js-5/.

However, what was omitted in this blog post and the guides, is the potentially powerful and risky “up the component tree” resolution of the ViewController. Read on to learn more with a Sencha Fiddle example…

Continue reading Declarative Listeners vs. Control

VN:F [1.9.22_1171]
Rating: 5.4/10 (24 votes cast)

Layout Run Error: Case of Hidden

It seems that I have started cataloging my experiences with the rather common Layout Run Error in ExtJS portals, as it’s one of the most frustrating errors to fix. Previous editions include:

This time I came across another rather simple scenario where I was troubleshooting something unrelated and in process was setting “hidden: false” on various components, in hopes of divide-and-conquering my way out of the issue.

Sure enough, got a “Layout Run Error” when I set one of my components as hidden. There was nothing particularly special about it – a Container extension sitting inside of another Container with “auto” layout. At that point I commented out my Container instead of setting it hidden: no more layout run error!

I decided not to spend time figuring out why this particular container didn’t like being hidden from the very beginning, especially considering this is in context of rather stale 4.2.1 ExtJS codebase. Nonetheless, the lesson is: even a simple act of having component declared as “hidden: true” initially can be enough to cause Layout Run Error.

VN:F [1.9.22_1171]
Rating: 5.8/10 (21 votes cast)