Pancake/French Toast/Store
Contents
- 1 User Scenarios
- 1.1 As a front-end developer, I need my program to be "push" notified of updates from the server and other data sources, so that the client can efficiently react to the most up-to-date information.
- 1.2 As a front-end developer, I need to be able to specifiy sub-sets of information and be notified when these sub-sets change, so that parts of the interface can react to the data that interests them.
- 1.3 As a front-end developer, I need to transform data coming from the server for display on the client-side. I need this transformed data to be "live". It should be updated when the original data is updated.
User Scenarios
As a front-end developer, I need my program to be "push" notified of updates from the server and other data sources, so that the client can efficiently react to the most up-to-date information.
By making the store an intermediary between the "client" (the app and its viewModel) and the server (or wherever data needs to come from) we give the store the role of a central dispatcher. Using an EventEmitter (like node.js) we can make the store an event source and the viewModel's properties the event sink. Now, any change to the store (e.g. incoming data from the server, or some other part of the UI) is broadcast to the queries (live resultsets) which it impacts. Sfoster
As a front-end developer, I need to be able to specifiy sub-sets of information and be notified when these sub-sets change, so that parts of the interface can react to the data that interests them.
There are a few ways to do this. Event channels is one. Filtering is another. If you think about it, event channels are really a domain specific language around querying change notifications. I prefer a filtering approach because predicate functions are more flexible than DSLs. If we still should want an event channel DSL, we could create one on top of predicate functions. -Gbrander
We have a simple-enough implementation borrowed from dojo's object store. Its query method accepts a dictionary of properties as predicate for the matching, and returns a lazy array of results. Furthermore, put/add/remove operations on the store trigger a check on these queries to determine if their results are impacted, and the change is sent to these resultsets via its observe mechanism. The query engine is pluggable - we can use a more sophisticated engine if necessary. The observe method on resultsets does not itself speak EventEmitter, but is easily wired into. There's an assumption baked into the design that reads are more frequent than writes - as each write essentially re-applies all open queries against the data. Sfoster
The client-side store is there to provide convenient access to data and abstracts away details of where the data originally comes from. To this end, we decorate records with a meta_type_
name: true
, making queries for types as easy as store.query({ meta_type_foo: true })
. Similarly, the composite nature of some responses is flattenned out - each object in s a response is filed separately Sfoster
As a front-end developer, I need to transform data coming from the server for display on the client-side. I need this transformed data to be "live". It should be updated when the original data is updated.
Knockout.js is a capable and flexible data-binding library. It provides for "extenders" - functions attached to an observable value which provide a hook to respond to value changes. A composeWith
extender allows us to specify a list of functions which can progressively filter, decorate and reduce values down to a render-ready value. The function composition happens once as the observable is assigned, and is executed each time the underlying value changes. Sfoster