Note: This page is here for historic reasons, the actual information is outdated. See Grid-SPF and Grid-Editing for the actual APIs.
4/5/2011 -- I've refactored and built out a better set of samples (over DataSourceSample.html below). Find these at: http://brado23.github.com/jquery-ui/grid-datamodel2/Default.html.
These samples are meant to be stepped through in your JS debugger, to see the various uses of the "data source" prototype that we've been discussing.
Here is a link to the "data source" prototype we've been discussing over the last couple weeks.
Both UI and non-UI controls (like a pager) can use this as an API to do loading/paging/sorting/filtering over local and remote data.
https://github.com/brado23/jquery-ui/blob/borisGrid/grid-datamodel2/DataSourceSample.html
This is not a classic request/response API. Rather, the "data source" manages the contents of the array of data objects to which it is bound, across multiple data read/write operations.
Control or app code will dynamically manipulate query options on the "data source" and call "refresh" on the "data source".
This "refresh" will cause the data source to update the contents of the array to which it is bound.
With the separation between "data source" and its array of data objects, jQuery data-linking can relate merely to the array of data objects and can be appropriately unaware of any additional data abstraction.
With in-development enhancements to data-linking, the "data source" should support CUD by listening to both array- and property-changed events, translating these into POSTs.
This separation of "data source" from array of data objects has the additional benefit of allowing for a somewhat declarative app construction pattern.
Notice in the sample that binding between control and data happens at the same, top-level JavaScript scope -- and not in some request/response callback from a data fetch.
The "data source" API itself deserves reworking. I selected the jQuery validator pattern of returning a non-jQuery "data source" object, allowing for fluent chaining of calls on the "data source".
Folks have expressed a desire to change to the jQuery UI pattern of not introducing a non-jQuery object.
Current data model prototype: https://github.com/jquery/jquery-ui/tree/grid/grid-datamodel
- Live demo: http://view.jqueryui.com/grid/grid-datamodel/data.html
- TODO
- should we use getters/setters or the datalink plugin?
- does it make sense to use the widget factory for non-DOM widgets?
- how should the datastore and datasource be related?
- SproutCore model: user always talks to store, store delegates to datasource
- MS model: user asks the datasource for a view/store and then interacts with the view
- how should we refer to item types?
- name (string)
- dataitem constructor
- datasource instance
- how should sorted/filtered data be stored?
- is there actually enough overhead in instantiating dataitem instances to use lazy initialization?
- what should the API for CRUD actions look like?
- should we use a generic observable array as the basis for dataitems?
Review of existing implementations:
- ExtJS
- Overview: http://www.sencha.com/learn/Manual:Data
- ExtJS API docs: http://dev.sencha.com/deploy/dev/docs/
- Grid Examples: http://dev.sencha.com/deploy/dev/examples/#sample-4
- Dynamic form interacting with embedded grid demo: http://dev.sencha.com/deploy/dev/examples/form/form-grid-access.html
- Ext.data API overview:
- Ext.data.DataProxy: Base class for implementing data retrieval. Provides implementations for Ext Direct, XmlHttpRequest (HttpProxy), JSONP (ScriptTagProxy) and local data (MemoryProxy). Used in combination with DataReader to provide data to a Store.
- Ext.data.Store: Client side cache of Record objects to provide input for GridPanel, Combobox or DataView. Bundled with ArrayStore, DirectStore, JsonStore, XmlStore and GroupingStore (to be used along with GroupingView). These are subclasses that make creating the store easier, by also creating the appropiate DataReader.
- Ext.data.Record: Encapsulates metadata describing data by creating constructors which can then be used by DataReader implementations to create actual data records
- Ext.data.DataReader: Base class for reading structured data from a data source and converting it to Ext.data.Record objects and metadata for use by Ext.data.Store. Has ArrayReader, JsonReader and XmlReader as bundled implementations
- Ext.data.Connection: Encapsulates a remote URL and related configuration. Can be used to configure a DataProxy
- Evaluation:
- The API has a lot of surface with the combination of Store, Record, Reader and Proxy. Considering jQuery's ajax module as an exposed base line, the remote data side could probably be simplified a lot, making the explicit proxy unnecessary or merging it into the Reader or Store.
- ArrayStore/ArrayReader are interesting in that they map nested arrays to array of objects. This works by providing metadata on the indicies of the nested array, mapping each index to a named property.
- Ext.Direct is a special case transport, as it requires a specific protocol implemented by the server. There are implementations for a lot of popular platforms.
- SproutCore
- Requires RubyGems >= 1.3.6 to install
- Has Controllers, Models and Views as primary building blocks, along with generators for these
- DataStore documentation
- API Overview:
- Record: Encapsulates data for a single item. Handles full CRUD. Contains business logic and validation. Actual data is stored in a Data Hash.
- Record Array: Contains many Record instances.
- Data Hash: Simple key/value storage for Record data.
- Store: In-memory storage for all data hashes.
- Ability to map property names from the original source to different names on the Record.
- Ability to create computed properties by specifying a function.
- Ability to define which properties affect the computed property.
- Ability to specify if the value is cacheable.
- Ability to create properties on Records that don't pass through to the Data Hash.
- Backbone
- Backbone.Model to describe data items (ala Ext.data.Record or SC.Record)
- get and set methods for attributes
- fetch for retrieving data from server into the model
- save to send to server
- additional methods/properties for handling IDs, validation
- change event on attribute changes, with some methods to deal with changes or trigger the event manually
- Backbone.Collection for model sets (ala Ext.data.Store or SC.RecordArray)
- create collection subclasses for specific model types, setting the model property to allow collection to create models from raw data
- contained models stored in models property, with get() and at() wrapper methods (and Underscore methods, e.g. forEach, map, reduce)
- crud methods: add, remove, get(id) - lookup via id-map, filled when adding models to collection, at(index) - direct access to models property via index
- fetch for retrieving default models from server
- refresh to manually fill collection with models
- models and collections can be nested: http://documentcloud.github.com/backbone/#FAQ-nested
- Backbone.sync implements default REST persistence strategy, can be overriden to customize
- used by both Collection.save/fetch and Model.save/fetch delegate
- handles updating models (create, read, update or delete a model) and reading collections
- expects JSON response with model attributes that were changed on the server or an array of model attributes for a Collection.fetch call
- option to fall back to POST method for update and delete requests
- Evaluation:
- Small API surface, with models and collections to be used with Backbone.View, which is slightly similar to $.widget, though with a render method to create HTML (using templates or whatever)
- No helpers for implementing custom datasource, e.g. XML-based transport; just relies on overriding of Backbone.sync
- No (obvious) support for handling larger collections, e.g. nothing in the API for paging collections. Can be added via custom collections.
- YUI
- SlickGrid
- Requires the data to be either an array or a data provider exposing
- getLength()
- getItem(index)
- optional getItemMetadata(index)
- Custom formatters & editors can extract & store data however they choose.
- Doesn't include a model per se, but has a DataView providing a filtered view of the data and driving the grid updates by firing onRowCountChanged and onRowsChanged events. Sorting, filtering, paging, grouping, aggregates, item CRUD are all implemented through the DataView (although the DataView is not required).
- Client-side pagination is done view DataView and a pager control wired together:
- Examples:
- DataView source:
- JsDataTrack
- datacontext defines CRUD operations
- datacontext handles remote/local data merging/conflicts
- a view on top of a datacontext provides a collection of items
- the view handles sorting/filtering
- Knockout
- MVVM (Model, View, ViewModel)
- API Overview:
- Model: Simple objects with properties
- View: HTML with data-bind attributes which contain JSON-like data
- View Model: Defines business logic
- Ability to define computed properties via ko.dependentObservable()
- automatically figures out which properties affect the computed property (explanation)
- JavascriptMVC
- Somewhat similar to SproutCore in its approach to building applications with apps, models, controllers and views, and generators for each
- Spry
- Main document page for Spry: http://labs.adobe.com/technologies/spry/docs.html
- Overview of the Spry Data support: http://labs.adobe.com/technologies/spry/articles/data_set_overview/index.html
- Spry API Document: http://labs.adobe.com/technologies/spry/articles/data_api/index.html
- Spry Samples/Demos:
- Spry Data Support in a Nutshell:
- Data Sets
- Loads data (JS Array, XML, HTML, JSON, CSV, or TSV) and flattens it into a tabular structure.
- Rows are objects, and the key/property names on the object are the column names.
- Column Types – Number, Date, String (Default), Markup
- Supports observers. Fires off Pre/Post notifications for Load, DataChanged, Sort, RequestSessionExpired, and RequestResponse.
- Supports Destructive and Non-Destructive Filtering.
- Supports Multi-Column Sorting.
- Client-Side Paging of Data
- Master/Detail support between Data Sets
- Can be used independently from Dynamic Regions.
- Dynamic Regions
- Free-form HTML markup with spry: processing instruction attributes on them, and data references.
- Regions are associated with one or more data sets.
- If the data in any of the data sets it relies on is modified/replaced, the region automatically re-generates its markup.
- Supports the notion of states and different markup can be used for each state.
- Supports observers. Fires off Pre/Post StateChange, and Update.
- Allows developers hooks for attaching behaviors before/afte the markup of a region changes.
- BoltJS
Comments (2)
Steve Rayner said
at 5:56 pm on Feb 25, 2011
typo on the setter;
$.widget( "ui.dataitem", {
defaultElement: null,
options: {
data: null
},
_create: function() {
},
get: function( key ) {
return this.options.data[ key ];
},
set: function( key, vaule ) { <----------- typo here
this.options.data[ key ] = value;
return this;
}
});
sorry havn't got to grips with git hub yet, so i don't know the proper etiquette for how to contribute.
Richard D. Worth said
at 6:42 pm on Feb 25, 2011
Steve,
Fixed thanks. In the future, for something like this, even if you're not quite set up with GitHub, see http://blog.jqueryui.com/2010/05/how-to-submit-a-fix-to-jquery-ui-the-easy-way/
You don't have permission to comment on this page.