47
The Once And Future Grid Nige White

SenchaCon 2016: The Once and Future Grid - Nige White

  • Upload
    sencha

  • View
    123

  • Download
    1

Embed Size (px)

Citation preview

Page 1: SenchaCon 2016: The Once and Future Grid - Nige White

The Once And Future Grid

Nige White

Page 2: SenchaCon 2016: The Once and Future Grid - Nige White

The Grid That Was…

XTemplates + cell renderers

(simple DOM replacement)

Page 3: SenchaCon 2016: The Once and Future Grid - Nige White

Classic Grid is a DataView with a BIG template

Four nested templates with embedded code.

1. The standard Component tpl which calls…

2. renderRows which uses

3. itemTemplate which uses

4. rowTemplate which uses

5. cellTemplate which calls…

6. Cell renderers

Page 4: SenchaCon 2016: The Once and Future Grid - Nige White

Challenges

• DOM churn.

• Changes replace DOM. Plugins, event handlers might “own” that DOM content.

• Scaling to today’s big apps. Multi thousand row grids.

Page 5: SenchaCon 2016: The Once and Future Grid - Nige White

Shortcomings

• View not configurable

• View not themeable

Header1 Header2 Header3

Data1.1 Data1.2 Data1.3

Data2.1 Data2.2 Data2.3

Page 6: SenchaCon 2016: The Once and Future Grid - Nige White

How have we mitigated these?

Page 7: SenchaCon 2016: The Once and Future Grid - Nige White

The Grid That Is…

XTemplates + cell renderers + Throttled view updates

+ Cell updaters

+ Minimal re-render

+ Minimal DOM update

+ Field dependencies

+ Buffered renderer

Page 8: SenchaCon 2016: The Once and Future Grid - Nige White

Classic Demo

Page 9: SenchaCon 2016: The Once and Future Grid - Nige White

Throttling/batching of DOM updates

View config:

{throttledUpdate: true

}Flushes batched changes every Ext.view.Table.updateDelay milliseconds

No long frames, small pulse of update activity every 200ms

Page 10: SenchaCon 2016: The Once and Future Grid - Nige White

Column updaters

• Similar to renderers, but only called for update. Passed cell’s DOM

updater: function(cellDom, value) {cellDom.firstChild.style.color = value < 0 ? ‘red’ : ‘green’;

}

Page 11: SenchaCon 2016: The Once and Future Grid - Nige White

Minimal DOM update

<tr class=“x-grid-row”><td class=“x-grid-cell”>

<div class=“x-grid-inner”>OldData

</div></td>

</tr>

<tr class=“x-grid-row”><td class=“x-grid-cell”>

<div class=“x-grid-inner”>NewData

</div></td>

</tr>

New, detached DOM Existing grid row

• Only the changed columns used to render detached row DOM• For each row:• Recursively update changed DOM attributes or text content

Page 12: SenchaCon 2016: The Once and Future Grid - Nige White

Field dependencies

• Relying on renderers to produce dependent values is unreliable.

• The calculated data does not really exist, so cannot be used.

• Renderers which use their full argument list mean no minimal DOM rerender

How do those fields change when we just set the new price?

Page 13: SenchaCon 2016: The Once and Future Grid - Nige White

Field dependencies // Depends on price field. Called whenever that is set{ name: 'trend', calculate: function(data) { // Avoid circular dependency by hiding the read of trend value var trend = data['trend'] || (data['trend'] = []);

trend.push(data.price); // Ext.data.Model class sees this! if (trend.length > 10) { trend.shift(); } return trend;}

Page 14: SenchaCon 2016: The Once and Future Grid - Nige White

Buffered renderer

Page 15: SenchaCon 2016: The Once and Future Grid - Nige White

Flush cycle. Nine rows to update

< 15ms

Page 16: SenchaCon 2016: The Once and Future Grid - Nige White

The Grid That Will Be…

Ext.List+ Configs

+ Data binding

+ Abstracted HTML away

Already Is…

Page 17: SenchaCon 2016: The Once and Future Grid - Nige White

The Grid That Will Be…

• Column locking

• Keyboard navigability

• Cell editing

• Group collapsing

• Group summaries

Page 18: SenchaCon 2016: The Once and Future Grid - Nige White

Where’s All The Magic Gone?

XTemplates + cell renderers

Cell updatersMinimal re-render

Minimal DOM copy

Throttled update

Buffered Renderer

Ext.ListExt.grid.Row

Ext.grid.cell.*

Binding → Configs

VM Scheduler config

List, infinite: true

Page 19: SenchaCon 2016: The Once and Future Grid - Nige White

Configs

Ext.define('Ext.Widget', {

config: { cls: null, ... }, ...

updateCls: function (cls, oldCls) { this.element.replaceCls(oldCls, cls); }});

getCls

setCls

On changes only!

Page 20: SenchaCon 2016: The Once and Future Grid - Nige White

Config generated setter

setCls: function (value) { var oldValue = this._cls; if (this.applyCls) { value = this.applyCls(value, oldValue); } if (value !== undefined && value !== oldValue) { this._cls = value; if (this.updateCls) { this.updateCls(value, oldValue); } } }

Transformvalues

Manageside-effects

Page 21: SenchaCon 2016: The Once and Future Grid - Nige White

Rows

Page 22: SenchaCon 2016: The Once and Future Grid - Nige White

Grid extends List

Ext.define('Ext.grid.Grid', { extend: 'Ext.List', xtype: 'grid',

defaultType: 'gridrow', infinite: true});

Create anExt.grid.Row

per visible record

Page 23: SenchaCon 2016: The Once and Future Grid - Nige White

Rows Are Containers of Cells

Page 24: SenchaCon 2016: The Once and Future Grid - Nige White

Not exactly…

Page 25: SenchaCon 2016: The Once and Future Grid - Nige White

Row extends Component

Ext.define('Ext.grid.Row', { extend: 'Ext.Component', xtype: 'gridrow',

...});

Page 26: SenchaCon 2016: The Once and Future Grid - Nige White

Rows Are Cell Managers.Also RowBody Widget Managers.

Page 27: SenchaCon 2016: The Once and Future Grid - Nige White

add() and remove() - No

Events - No

Hierarchy – Yes

ViewModels - Yes

Page 28: SenchaCon 2016: The Once and Future Grid - Nige White

Modern Demo

Page 29: SenchaCon 2016: The Once and Future Grid - Nige White

Throttling/batching of DOM updates

View config:

viewModel: { scheduler: { tickDelay: 200 }}Flushes batched changes every 200 milliseconds

No long frames, even smaller pulse of update activity every 200ms

Page 30: SenchaCon 2016: The Once and Future Grid - Nige White

Changes distributed selectivelyRow’s ViewModel

Cell CellCell

RowBodyWidget

setValue(boundValue)setValue(boundValue) setInnerCls(boundValue)

setRecord(boundRecord)

Page 31: SenchaCon 2016: The Once and Future Grid - Nige White

Flush cycle. Eleven rows to update

< 3ms

Page 32: SenchaCon 2016: The Once and Future Grid - Nige White

Styling Rows

Page 33: SenchaCon 2016: The Once and Future Grid - Nige White

Classic

items: [{ xtype: 'grid', viewConfig: { getRowClass: function (rec) { return rec.get("valid") ? "row-valid" : "row-error"; } }}

Page 34: SenchaCon 2016: The Once and Future Grid - Nige White

Modernitems: [{ xtype: 'grid', itemConfig: { cls: 'row-class', viewModel: { type: 'row-model' }, bind: { cls: '{record.change > 0 ? "ticker-gain" : "ticker-loss”}’ } }}]

Page 35: SenchaCon 2016: The Once and Future Grid - Nige White

Cells

Page 36: SenchaCon 2016: The Once and Future Grid - Nige White

columnsdrive cell

creation and order

Page 37: SenchaCon 2016: The Once and Future Grid - Nige White

Columns

items: [{ xtype: 'grid', columns: [{ // xtype: 'column', text: 'Heading', cell: { // xtype: 'gridcell', cls: 'mycell' } }]

CellConfiguratio

n

Page 38: SenchaCon 2016: The Once and Future Grid - Nige White

ai

Grid Columns

bi ci

A B C

rows[i]

headerxtype: 'grid',columns: [{ text: '...', cell: {...}}]

Page 39: SenchaCon 2016: The Once and Future Grid - Nige White

Base

Text

Boolean

Cell

Date

Number

TreeWidget

Cell Classes

Page 40: SenchaCon 2016: The Once and Future Grid - Nige White

Faster. More secure.

• Cell widget config updaters do minimal change.

• Data is HTML encoded by default.

Page 41: SenchaCon 2016: The Once and Future Grid - Nige White

htmlEncode: true by default

<div style="position:fixed;top:0; left:0;width:10000px;height:10000px;z-index:10" onmouseover="alert('Hack!')"></div>

<img src="\\" onerror="alert('hack')"</img>

<img src="http://evil.org/"></img>

Page 42: SenchaCon 2016: The Once and Future Grid - Nige White

What if we’re not rapidly changing?

Scrolling data is exactly that when we are using buffered rendering.

New DOM has to be created to show rows in the direction of scroll.

Page 43: SenchaCon 2016: The Once and Future Grid - Nige White

Row

Modern Grid is managed Row Widgets

Row

VisibleSpares

Row 1Row 2Row 3

Page 44: SenchaCon 2016: The Once and Future Grid - Nige White

Modern Grid is managed Row Widgets

scro

ll[0]

[1]

[2]

[3]

[4]setRecord(rec[5])

Row 4

Row 1Row 2Row 3

Row 0

[5]

Row 5

Page 45: SenchaCon 2016: The Once and Future Grid - Nige White

Conclusion

• Less openly HTML centred concept.

• Widgets abstract away from HTML, each can carry CSS classes for theming.

• HTML + CSS power still there for decorative purposes – tpl config.

• Analogous to UIWebView.

• If you need different appearance and behaviour, prefer a custom component.

Page 46: SenchaCon 2016: The Once and Future Grid - Nige White

Please Take the Survey in the Mobile App

• Navigate to this session in the mobile app

• Click on “Evaluate Session”

• Respondents will be entered into a drawing to win one of five $50 Amazon gift cards

Page 47: SenchaCon 2016: The Once and Future Grid - Nige White