These are my early thoughts on how to structure DataTable in 3.5.0. Feedback is welcome in the comments.
new Y.DataTable({...});
new Y.DataTable.Base({...});
Y.DataTable.Base = Y.Base.create('datatable', Y.Widget, [Y.DataTable.Core]);
Y.DataTable = Y.mix(
Y.Base.create('datatable', Y.DataTable.Base, []),
Y.DataTable, true);
Class extensions CAN (if non-invasive by default)
Y.Base.mix(Y.DataTable, [ Y.DataTable.Sortable ]);
new Y.DataTable({
data: [{ ... }, { ... }, ... ]
data: modelList
data: {
source: url, function, xml
type: 'json'
schema: { ... }
}
columns: (optional) [ key, key, { key: key, config: stuff, ... }, ... ]
recordType: (optional) ModelClass
headerView: (optional) ViewClass
bodyView: (optional) ViewClass
footerView: (optional) ViewClass
summary: (optional) 'string'
caption: (optional) 'string'
});
instance
.data = modelListInstance
.head = viewInstance
.body = viewInstance
.foot = viewInstance
-
Y.DataTable.Core
Everything added to Y.Widget to make DataTable.Base
-
Y.DataTable.HeaderView
-
Y.DataTable.BodyView
-
Y.DataTable.FooterView
Used by DataTable(.Base) to render the table contents.
Referenced via configuration, not composition.
-
Y.DataTable.Source
Optional class extension.
Adds support
data
config to generate ML with DataSource load. -
Y.DataTable.Scrollable
Optional class extension.
Adds support for scrolling table. May be used to create a third instantiable class.
-
Y.DataTable.ScrollingBodyView
Used in place of DataTable.BodyView to render the scrolling table. May not be necessary?
-
Y.DataTable.Sortable
Adds support for sorting headers and sortable config.
instance.render(...)
- build <table> (markup only or off DOM node?)
- instantiate header, body, footer views passing
- the DT instance
- the created table?
- the
data
ModelList?
- call each view's render()
Logic for reacting to user input is moved to the View classes
Concern: string based rendering would have viewX.render() return a string or populate a property, but it has requirements of the DT renderer
instance.load(...)
Pass through to this.data.load(...). Let the ModelList be responsible for data interaction.
- No ModelList is provided in
data
configuration AND - No
recordType
is provided in configuration
- Use the first item in the data array to build ATTRS and Y.Base.create(...)
- If data is empty, use columns?
Yep, been that way since the beginning.
https://github.com/lsmith/yui3/blob/dtxpr/src/datatable/js/core.js#L324
The display order of the rows can be considered a view-only concern (lsmith/yui3#7). John Lindal raised this point a while back, and I agree on an engineering level. All the same, just sorting the DT's ML would be a lot easier, and probably less fragile.
Your code example reinforces my point about the use of View's
events
config. In order to use it, you've defined a new View subclass that replaces the currentheaderView
. I do want the interaction to be decoupled, and using events to relay info between the DT and views is good, but why would the view fire a sort event if it didn't have any associated action? It will sort in response to a change in itsmodelList
. If the DT will sort the ML, that should be the defaultFn of asort
event fired from the DT. If the sorting is kept a view concern, then... things get even more complicated I think. And how would you make the current HeaderView capable of firing a sort event? That's why I'm thinking plugins, but (circling back) that doesn't use the View'sevents
config.