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?
@desai
Yeah, I backed off wanting Model mixed into DT. The important model state is defined by the records, I figure. Other features might introduce state, but at this point, I suspect they would be UI related, making it a less compelling argument. We'll see as development progresses if this will be an issue.
Not sure what you mean. They will be instantiated with the DataTable instance, the data ModelList, and the column configuration.
Yes, or at least DT will expect them to honor at least a part of the View API by duck type. I don't plan on testing with instanceof. I thought I made it fairly clear in the gist:
Agreed, there will need to be a migration guide. Re columns and columnset, at this point, I want to see if I can get away with leaving the
columns
config as a plan array of objects. This would allow feature modules to read properties from the column config without needing to also modify the Column.ATTRS to have the custom configs preserved. Right now,sortable
, for example, is defined in the Column class even though it does nothing unlessdatatable-sort
is also used.@ericf,
They are properties for convenient access, and because IMO, a DT is a composite of interesting parts. Attributes define state and configuration, but not composition. Specifically
instance.data
will refer to the same object returned frominstance.get('data');
, but it will be accessed to get to its properties or methods, soinstance.data.someMethod()
feels more direct thaninstance.get('data').someMethod()
. Thedata
attribute starts feeling less like state/configuration when interacted with though get().Similarly,
head
,body
, andfoot
are parts of the DT. I wanted to minimize the amount of class creation needed to instantiate a DT, but I plan on thebodyView
etc configs accepting either a View class or instance. The config would keep the passed value, but the property would be the instance. If the DT is instantiated withbodyView: viewInstance
, theninstance.get('bodyView')
would be equivalent toinstance.body
.No, because the analogy would be header, body, footer => thead, tbody, tfoot, but a) the container is at least one table, which defines the dimensions of the children as part of its native behavior, b) rendering order for tables is thead, tfoot, tbody, and c) there are other children of the table element as well such as caption and column/colgroup. In the end, I expect I would get little benefit from StdMod's artificial structure and would wind up rewriting a bunch of it to fit the table ordering rules. Also, I don't like its API :)