Overview
data-tier
('tier' from 'to tie') is a two way binding (MVVM) service targeting client (browser) HTML/Javascript applications.
data-tier.js
relies on an Observable
-driven event cycle, having an embedded object-observer
as the default Observable
provider.
It is possible to provide custom Observable
implementation. In this case you may want to use lighter data-tier-wo-oo.js
where object-observer.js
opted out.
Support matrix: 49+ | 44+ | 13+
Support matrix is currently as wide as that of object-observer
, assuming that in most of the cases consumers will not provide their own object observer, but will use an embedded one.
data-tier
supports custom elements as well, obviously this functionality is available only on supporting environments.
Versions
-
0.6.19
- Fixed incorrect behavior when
tie-property
configured on the element after it was added to the DOM
-
0.6.18
-
0.6.17
- Added
tie-property
OOTB controller - having parameter syntax path.to.data => propName
it is made possible to tie to arbitrary element property (yes, this is having CustomElements
in mind)
-
0.6.16
- Fixed potential issue with empty (
null
) object traversal in deep tying
-
0.6.15
- Fixed issue no. 11
- Moved most of the changes here, while here will be shown only a most recent versions
Loading the Library
There are 2 ways to load the library: into a window
global scope, or a custom scope provided by you.
- Simple reference (script tag) to the
data-tier.js
/data-tier.min.js
in your HTML will load it into the global scope:
<script src="data-tier.min.js"></script>
<script>
let person = { name: 'Uriya', age: 8 };
DataTier.ties.create('person', person);
DataTier.ties.create('settings');
</script>
-
tie person
has its data
property set to Observable.from(person)
, original person
object remains untouched and its own changes aren't being watched
-
tie settings
has its data
as null
, it may be set to any object later on
-
The snippet below exemplifies how to load the library into a custom scope (add error handling as appropriate):
let customNamespace = {},
person = { name: 'Nava', age: 6 };
fetch('data-tier.min.js').then(function (response) {
if (response.status === 200) {
response.text().then(function (code) {
Function(code).call(customNamespace);
customNamespace.DataTier.ties.create('person', person);
});
}
});
- If an embedded
object-observer
employed, it is even more preferable to create the Tie
from a plain JS object - Minified version is also available for both distributions, with and without
object-observer.js
Basic concepts
My, definitely opinionated, insights of how client application should look like in general and how data-tier
library comes into that picture can be found here. That would probably be the most completed overview of the library's overall usage intent.
Here I'll just outline the very essentials, namely 2 main concepts: Tie
and Controller
.
Tie
Tie
holds an observable data structure associated with tie's name, it's about what to tie.
Thus, ties serve most and foremost data segregation and management purposes.
Having the following data structure:
let bands = [
{
id: 1234,
name: 'Dream Theater',
since: 1985,
albums: [
{ id: 2345, name: 'When Dream and Day Unite', since: 1988 },
{ id: 2346, name: 'Images and Words', since: 1991 }
]
}
];
bands.totalTooltip = generateTooltipText();
one can create a tie named, say, 'bandsTie', having its data set to the bands array:
let bandsDataStore = DataTier.ties.create('bandsTie', bands);
and then tie any UI element to it via the tie name and the path:
<span data-tie-text="bandsTie.length"
data-tie-tooltip="bandsTie.totalTooltip">
</span>
<div>
<template data-tie-list="bandsTie.0.albums => album">
<span data-tie-text="album.name"></span>
</template>
</div>
where:
- the first item in the path is always the tie's name
bandsTie.0
- refer to the whole object at index 0 of our arraybandsTie.length
- length
property, inherited from the native Array
, may also be usedbandsTie.0.name
- path can get deeper...bandsTie.0.albums.1.since
- ...actually, it can get to any level of deepness
Basically, it is possible to create a single dataset for the whole application, making a single 'uber-tie' from it and operating everything from there, but it should be considered as a bad practice.
Having say that, I'll note, that there is no limitations on the size or the structure complexity of the tied model, nor there are any negative effects of those on application performance.
Tie
object not only meant to hold the link between the data and its namespace, but also tie's specific configurations/customizations and data management APIs.
For more details see API reference.
Controller
Controller
is a holder of the transition logic, it's about how to translate the data from/to view/data.
Each controller has it's own unique name given to it upon registration.
Controllers are applied via the DOM's data-*
attributes joining the data-
prefix with rule's name: for example data-tie-text
employs the controller 'tieText'.
<span data-tie-text="bandsTie.length"
data-tie-tooltip="bandsTie.totalTooltip">
</span>
<div>
<template data-tie-list="bandsTie.0.albums => album">
<span data-tie-text="album.name"></span>
</template>
</div>
In the first part we tie between the span
(view) and the model (we have tied it to both, length
and totalTooltip
values), while using 2 different OOTB controllers: 'tieText', 'tieTooltip'.
Attributes' values (bandsTie.length
, bandsTie.totalTooltip
) are controllers' configurations for this specific instance and their syntax/content is part of each controller's own API.
Thus, in the second part a template
element tied by another OOTB controller: 'tieList'.
This one expects a richer content in its configuration: tie name and path for sure, but also some name for an item within iteration (here - 'album', and see its usage in the inner span element).
OOTB provided controllers reviewed in the Controllers reference.
This set will eventually be updated and enhanced.
But even more important is the fact, that any custom controllers may be provided by the consuming application.
This can be done at any phase of application's lifecycle, so that there is no special ceremony around it whatsoever.
Controllers' management described in the relevant section in API reference.
Documentation
Tutorials
API reference
OOTB Controllers reference