Linen (line-in) maps API's to bindable objects
, and collections
. At classdojo, we use linen
to abstract our API from front-end, so we don't necessarily depend on any sort of API while developing new components. This allows us to rapidly build prototypes which can be wired up later.
Here's an example person schema:
var linen = require("linen")();
linen.addSchema({
name: "person",
fields: {
firstName: "string",
lastName: "string",
fullName: {
$get: function(model) {
return model.get("first_name") + " " + model.get("last_name");
},
$set: function(model, value) {
var nameParts = String(value).split(" ")
model.set("first_name", nameParts.shift());
model.set("last_name", nameParts.join(" "));
},
$bind: ["first_name", "last_name"]
},
friends: [{
$ref: "person",
$fetch: function(payload, next) {
transport.fetch(payload.method, "/people/" + payload.model.get("_id") + "/friends", next);
}
}]
},
fetch: function(payload, next) {
transport.fetch(payload.method, "/people/" + (payload.model.get("_id") || ""), next);
}
});
To use the schema, simply call the following:
var person = linen.model("person"),
existingPerson = linen.model("person", "someId");
Linen works by overriding the bind
method to fetch from any API you have setup, so when you call:
existingPerson.bind("firstName").to(function(name) {
console.log(name);
}).now();
The existingPerson
will asynchronously call .to(fn)
when it's been loaded from the server. This is useful when data-binding to any sort of UI component, such as rivets.js, or paperclip.js.
Here's another example of data-binding to linen
models:
existingPerson.bind("friends").to(function(friends) {
friends.at(0).bind("firstName").once().to(function(name) {
}).now();
}).now();
The above examples make it easy to abstract models from any API. To demonstrate this, here's an example of using dummy data
:
var existingPerson = new bindable.Object({
firstName: "Ron",
lastName: "Burgundy",
friends: [
new bindable.Object({
firstName: "Brian",
lastName: "Fontana"
}),
new bindable.Object({
firstName: "Brick",
lastName: "Tamland"
}),
new bindable.Object({
firstName: "Champ",
lastName: "Kind"
})
]
});
existingPerson.bind("firstName").to(function(name) {
console.log(name);
}).now();
existingPerson.bind("friends").to(function(friends) {
friends.at(0).bind("firstName").once().to(function(name) {
console.log(name);
}).now();
}).now();
API
linen()
Returns a new linen instance
linen.addSchema(definition)
adds a new schema
definition
Inspired by mongoose:
linen.addSchema({
firstName: {
}
});
linen.model(schemaName[, modelId ])
returns a new, or existing model