@@ -239,46 +239,99 @@ class Row extends Component {
239239
240240 vdom . cls = rowCls ;
241241
242- for ( i = 0 ; i < countColumns ; i ++ ) {
243- isMounted = i >= mountedColumns [ 0 ] && i <= mountedColumns [ 1 ] ;
244- column = columns . getAt ( i ) ;
242+ // Pass 1: Render Pooled Cells (hideMode === 'removeDom')
243+ // We only render these if they are within the mounted range.
244+ // This loop is O(Viewport) - highly efficient.
245+ for ( i = mountedColumns [ 0 ] ; i <= mountedColumns [ 1 ] ; i ++ ) {
246+ column = columns . getAt ( i ) ;
247+
248+ // Sanity check for bounds (e.g. if column count changed)
249+ if ( ! column ) continue ;
250+
251+ if ( column . hideMode === 'removeDom' ) {
252+ cellConfig = me . applyRendererOutput ( {
253+ cellId : `${ me . id } __cell-${ i % gridBody . cellPoolSize } ` ,
254+ column,
255+ columnIndex : i ,
256+ record,
257+ rowIndex,
258+ silent
259+ } ) ;
260+
261+ if ( column . dock ) {
262+ cellConfig . cls = [ 'neo-locked' , ...cellConfig . cls || [ ] ]
263+ }
245264
246- if ( ! isMounted && column . hideMode === 'removeDom' ) {
247- continue
248- }
265+ columnPosition = gridBody . columnPositions . get ( column . dataField ) ;
249266
250- cellConfig = me . applyRendererOutput ( { column, columnIndex : i , record, rowIndex, silent} ) ;
267+ if ( ! columnPosition ) {
268+ continue
269+ }
251270
252- if ( column . dock ) {
253- cellConfig . cls = [ 'neo-locked' , ...cellConfig . cls || [ ] ]
254- }
271+ cellConfig . style = {
272+ ...cellConfig . style ,
273+ left : columnPosition . x + 'px' ,
274+ width : columnPosition . width + 'px'
275+ } ;
255276
256- columnPosition = gridBody . columnPositions . get ( column . dataField ) ;
277+ // Happens during a column header drag OP, when leaving the painted range
278+ if ( columnPosition . hidden ) {
279+ cellConfig . style . visibility = 'hidden'
280+ }
257281
258- if ( ! columnPosition ) {
259- continue
282+ vdom . cn . push ( cellConfig )
260283 }
284+ }
261285
262- cellConfig . style = {
263- ...cellConfig . style ,
264- left : columnPosition . x + 'px' ,
265- width : columnPosition . width + 'px'
266- } ;
286+ // Pass 2: Render Permanent Cells (hideMode !== 'removeDom')
287+ // We MUST render these even if they are off-screen to preserve their DOM state (e.g. Canvas context).
288+ // This loop is O(TotalColumns), but typically few columns use this mode.
289+ for ( i = 0 ; i < countColumns ; i ++ ) {
290+ column = columns . getAt ( i ) ;
291+
292+ if ( column . hideMode !== 'removeDom' ) {
293+ isMounted = i >= mountedColumns [ 0 ] && i <= mountedColumns [ 1 ] ;
294+
295+ cellConfig = me . applyRendererOutput ( {
296+ cellId : `${ me . id } __${ column . dataField } ` ,
297+ column,
298+ columnIndex : i ,
299+ record,
300+ rowIndex,
301+ silent
302+ } ) ;
303+
304+ if ( column . dock ) {
305+ cellConfig . cls = [ 'neo-locked' , ...cellConfig . cls || [ ] ]
306+ }
267307
268- // Happens during a column header drag OP, when leaving the painted range
269- if ( isMounted ) {
270- if ( columnPosition . hidden ) {
271- cellConfig . style . visibility = 'hidden'
308+ columnPosition = gridBody . columnPositions . get ( column . dataField ) ;
309+
310+ if ( ! columnPosition ) {
311+ continue
272312 }
273- } else {
274- if ( column . hideMode === 'visibility' ) {
275- cellConfig . style . visibility = 'hidden'
276- } else if ( column . hideMode === 'display' ) {
277- cellConfig . style . display = 'none'
313+
314+ cellConfig . style = {
315+ ...cellConfig . style ,
316+ left : columnPosition . x + 'px' ,
317+ width : columnPosition . width + 'px'
318+ } ;
319+
320+ // Visibility Logic
321+ if ( isMounted ) {
322+ if ( columnPosition . hidden ) {
323+ cellConfig . style . visibility = 'hidden'
324+ }
325+ } else {
326+ if ( column . hideMode === 'visibility' ) {
327+ cellConfig . style . visibility = 'hidden'
328+ } else if ( column . hideMode === 'display' ) {
329+ cellConfig . style . display = 'none'
330+ }
278331 }
279- }
280332
281- vdom . cn . push ( cellConfig )
333+ vdom . cn . push ( cellConfig )
334+ }
282335 }
283336
284337 ! silent && me . update ( )
0 commit comments