Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ericgj/model
Simple, framework-agnostic, persistent models for the browser
https://github.com/ericgj/model
Last synced: 9 days ago
JSON representation
Simple, framework-agnostic, persistent models for the browser
- Host: GitHub
- URL: https://github.com/ericgj/model
- Owner: ericgj
- Created: 2014-07-05T18:40:16.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2015-07-07T19:42:41.000Z (over 9 years ago)
- Last Synced: 2024-11-15T12:27:37.804Z (2 months ago)
- Language: JavaScript
- Homepage:
- Size: 219 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: Readme.md
- Changelog: History.md
Awesome Lists containing this project
README
# model
Simple, framework-agnostic, persistent models for the browser.
* Declarative attributes based on [JSON Schema][jsonschema]
* Defaults
* Customizable type casting
* Observable `set` and `reset`
* No sync layer## Installation
Install with [component(1)](http://component.io):
$ component install ericgj/model
# var model = require('model')()
Model constructor.
#
model.attr(name [, schema])
model.attr(object)Define attribute `name` with given `schema` object. The schema can specify
a default value (`default`), a data type (`type`), and whether or not the
attribute is read-only (`readOnly`).The single-argument form allows you to specify multiple attributes by passing
an object whose keys are attribute names and whose values are schemas.#
model.cast(name, function)
model.cast(object)Define a custom conversion function for the specified attribute `name`. When
`type` is specified for an attribute, the attribute is cast using build-in cast
functions. Specifying `cast` overrides this default casting.Typically, `cast` is used in converting string values (from CSV data or view
input elements, for instance), into a useful representation.For instance:
```js
model.attr('tags', { type: 'string' })
.attr('count', { type: 'number' })
.cast('tags', function(s){ return String(s).split(','); })
.cast('count', function(s){ return +s; })
```The single-argument form allows you to specify multiple casts by passing
an object whose keys are attribute names and whose values are cast functions.#
model.calc(name, function)
model.calc(object)Define a calculated attribute `name` using the specified `function`. Note the
function is called on the _casted_ current value, not the raw value.The single-argument form allows you to specify multiple calculations by passing
an object whose keys are attribute names and whose values are calc functions.# var instance = model([object])
Construct an instance of the model by calling the model as a function. If
`object` is passed, it extends the default.# instance.value()
Get the current value (plain object) of the instance. Attributes are casted
if their type or an explicit cast has been specified. Attributes on the
original object that are not specified in the model are passed through
unchanged. Calculated attributes are also included.# instance.changedValue()
Get the _changed_ value (plain object) of the instance. All specified,
non-read-only attributes with a current value are included. Read-only and
unspecified attributes are _not_ included, nor are calculated attributes.# instance.change()
Get an object representing the applied changes made to attributes. Useful for
`PATCH`-style updates.# instance.changes()
Get an array of all changes as `[attribute, value]` pairs.
# instance.dirty()
Sugar for `instance.changes().length > 0` .
# instance.get(attribute)
Get the current (casted) value of the attribute.
#
instance.set(attribute, value)
instance.set(object)Set an attribute (or attributes if an object is passed). If the attribute is
`readOnly`, or attribute is not specified in the model, `set` has no effect.Dispatches a 'set' event with the attribute and value as parameters. See
below, [Events](#events).# instance.reset([object])
Resets internal state of the instance without losing event observers. In
other words, it's equivalent to creating a new model instance, except that
any event observers on the instance are maintained. If no object is
passed, then it simply clears the changes but does not change the underlying
base object passed in the constructor. Dispatches a 'reset' event.Events can be observed either at the _model_ or _instance_ level. The callback
signature is the same, except the model events have the instance as the first
parameter. If you have used [component/model][compmodel] or [modella][modella],
this should seem familiar.#
model.on('set', handler)
instance.on('set', handler)Fired on `instance.set`, calling the handler with the passed attribute and
value. Note `set(object)` calls result in multiple `set` events, one per
attribute-value pair.#
model.on('reset', handler)
instance.on('reset', handler)Fired on `instance.reset`, calling the handler with the passed object.
Note this is the "raw" passed object, not the `model.value()`.#
model.on('setting', handler)
instance.on('setting', handler)Same as `set`, but fired _before_ state changes.
#
model.on('resetting', handler)
instance.on('resetting', handler)Same as `reset`, but fired _before_ state changes.
Note that `setting` and `resetting` events can be used to check existing
state in an event handler:```js
model.on('setting', function(instance,attr,val){
var oldval = instance.get(attr);
// do something comparing oldval with val
})instance.on('resetting', function(obj){
var oldobj = instance.value()
// do something comparing oldobj with obj
})```
## TODO
* metadata
* validation
* model construction directly via JSON Schema## License
The MIT License (MIT)
Copyright (c) 2014 Eric Gjertsen ``
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.[jsonschema]: http://json-schema.org
[compmodel]: https://github.com/component/model
[modella]: https://github.com/modella/modella