Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJSIV-9005 in 4.2.0 Sprint 4 (GA).
  1. #1
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    140
    Vote Rating
    7
    brian428 is on a distinguished road

      0  

    Default Ext.view.NodeCache must confirm element exists before trying to use it

    Ext.view.NodeCache must confirm element exists before trying to use it


    Using a grid with BufferedRenderer, if an item is deliberately removed from the backing store and that item's index isn't in the current set of viewable indexes, an error is thrown during NodeCache.removeElement().

    Since the index falls within the range of fromIndex and endIndex, it tries to locate the element and run el.setAttribute('data-recordIndex', index) on it. This neglects the fact that even though the index is within fromIndex and endIndex, it is NOT present in the more limited set of indexes in the elements object.

    I'm not sure if this means fromIndex and endIndex need to be changed to reflect only the indexes that are actually rendered, or if a check just needs to be made prior to the setAttribute() call to confirm an element was found. In my case, I manually changed the condition on line 272 of NodeCache from

    Code:
    if (fromIndex <= me.endIndex)
    to

    Code:
    if (fromIndex <= me.endIndex && elements.hasOwnProperty(index))
    This gets around the problem and everything seems to work correctly. I'm also not sure if there are other views that may be susceptible to this issue, or if NodeCache is the only view that could be affected by using the BufferedRenderer.

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    St. Louis, MO
    Posts
    33,599
    Vote Rating
    434
    mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of

      0  

    Default


    I opened up the buffer-grid.html example and used this in the console with no error:

    Code:
    Ext.ComponentQuery.query('gridpanel')[0].getStore().removeAt(4000);
    Record at 4,000 index isn't in view as I haven't scrolled at all. Did I miss a step?
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    http://www.JSONPLint.com - Source to lint your JSONP!

    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    140
    Vote Rating
    7
    brian428 is on a distinguished road

      0  

    Default


    Yes, looks like it has to do with actually scrolling. For example, if you scroll all the way to the end of the grid, then try to run Ext.ComponentQuery.query('gridpanel')[0].getStore().removeAt(0);, you'll get the error.

  4. #4
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    140
    Vote Rating
    7
    brian428 is on a distinguished road

      0  

    Default


    In case it narrows down the cause, a bit more playing seems to indicate that it ONLY happens if you scroll all the way to the end and then try to remove an item that's above the top of the viewable list.

  5. #5
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    St. Louis, MO
    Posts
    33,599
    Vote Rating
    434
    mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of mitchellsimoens has much to be proud of

      0  

    Default


    Yeah, seems the scrolling is the key. Will report this into our bug system.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    http://www.JSONPLint.com - Source to lint your JSONP!

    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!

    When posting code, please use BBCode's CODE tags.

  6. #6
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,458
    Vote Rating
    20
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    What if you add the following override?

    Code:
    Ext.override(Ext.grid.plugin.BufferedRendererTableView, {
    
        onRemove: function(store, records, indices) {
            var bufferedRenderer = this.bufferedRenderer;
    
            // The view has the full complement of rows that the BufferedRenderer needs - must refresh
            if (bufferedRenderer && this.all.getCount() >= bufferedRenderer.viewSize) {
    
                // If the removed range is entirely outside the rendered range, we don't care about removal.
                if (indices[0] < this.all.startIndex || indices[indices.length - 1] > this.all.endIndex) {
                    return;
                }
    
                this.onDataRefresh();
            }
            // No BufferedRenderer present
            // or
            // View has not yet reached the viewSize: we can add as normal.
            else {
                this.callParent([store, records, indices]);
            }
        }
    });

  7. #7
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,458
    Vote Rating
    20
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    No, that's no good. It must update the view on delete to bump the data upwards if a row above has been deleted...

    Hmm...

  8. #8
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,458
    Vote Rating
    20
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    I can't make it throw an error.

    I run examples/grid/buffer-grid.html

    Then get a reference to the store, and scroll the data to the end.

    Then do

    Code:
    store.removeAt(0);
    It goes to row zero, so the preserveScrollOnRefresh needs to be set if buffered rendering is happening (I'll fix that)

    But it does not throw an error. How can I reproduce this?

  9. #9
    Sencha Premium Member
    Join Date
    Feb 2012
    Posts
    140
    Vote Rating
    7
    brian428 is on a distinguished road

      0  

    Default


    Animal, are you saying if you do exactly what I did above (in the browser console), you don't get an error?

  10. #10
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,458
    Vote Rating
    20
    Animal is a jewel in the rough Animal is a jewel in the rough Animal is a jewel in the rough

      0  

    Default


    Yep!