![](http://habrastorage.org/getpro/habr/avatars/935/6cd/484/9356cd484b9da70c975ecc4d02078a4e.jpg)
Derby.js TODO or not TODO
- Tutorial
![](https://habrastorage.org/getpro/habr/post_images/0e1/af5/4eb/0e1af54ebb79c4071b06653d8635bd47.jpg)
Some programmers have already realized the prospects and set about studying Derby. Others are watching with interest what is happening, but are not ready at the moment to part with their favorite framework for various reasons. Still others are minus Derby tutorials, believing that this will somehow stop progress and the impending wave of full-stack frameworks.
Well, our steam locomotive is gaining momentum and today we will delve into our Derby research.
Set up the environment and create a bare project .
/lib/app/index.js
app.get('/', function(page, model) {
model.subscribe('todos', function(err) {
if (!model.get('todos')) {
model.add('todos', {text: 'Todo 1'});
model.add('todos', {text: 'Todo 2'});
}
page.render();
})
});
Here we signed up for the entire todos collection. In the future, we will do all our data manipulations precisely after we subscribed to them, because before subscribe, our model is empty. Now add a couple of objects there if there is no such collection.
model.add is a wrapper over model.set. The only thing she does is generate the id itself. We could write like this:
var id = model.id(); //так генеририруется guid с помощью require('node-uuid').v4()
model.set('todos.' + id, {text: 'Todo 1'});
Our collection is a js object. If done
model.get('todos')
, we get:{
"e1b8075c-de9a-458a-aa3c-e9b383691521":
{
"text":"Todo 1",
"id":"e1b8075c-de9a-458a-aa3c-e9b383691521"
},
"26cd5f4a-c503-4c25-aeeb-a28c8c034d08":
{
"text":"Todo 2",
"id":"26cd5f4a-c503-4c25-aeeb-a28c8c034d08"
}
}
This is good if we want to get objects from it by id:
var todo = model.get('todos.e1b8075c-de9a-458a-aa3c-e9b383691521');
But if we want to output our todos in html, then we would be better off with an array. Meet, we have a wonderful thing - filter:
app.get('/', function(page, model) {
model.subscribe('todos', function(err) {
if (!model.get('todos')) {
model.add('todos', {text: 'Todo 1'});
model.add('todos', {text: 'Todo 2'});
}
var filter = model.filter('todos');
filter.ref('_page.todos');
page.render();
})
});
/views/app/index.html
{#each _page.todos as :todo}
{:todo.text}
{/}
Here we create a filter for todos. It dynamically monitors changes to this collection and displays the result in '_page.todos' using refList, about which a little later. But the filter would not be a filter if it did not know how to filter. We can do something like this:
var todos = model.filter('todos', function(todo) {
return todo.text == 'Todo1';
}).get();
Here, we immediately extracted the filtered array.
var todos = model.filter('todos').sort('text').get();
And here we also sorted by the text field.
Neither filter nor sort know anything about your database. They only operate on the data that is in the model. Fill the model before this!
Duck what's up with refList? These are the so-called references. Allows you to bind data between two paths. They rarely have to be used directly, but they are used, for example, by filter and queries.
app.get('/', function(page, model) {
model.subscribe('todos', function(err) {
if (!model.get('todos')) {
model.add('todos', {text: 'Todo 1'});
model.add('todos', {text: 'Todo 2'});
}
var ids = Object.keys(model.get('todos'));
model.set('_page.ids', ids)
model.refList('_page.todos', 'todos', '_page.ids');
page.render();
})
});
ids is a list of id of those todo that we want to get as a result. They also specify the order in the array '_page.todos'. We can change the '_page.ids' and this will immediately affect the '_page.todos'.
Let's torture subscribe:
model.subscribe('todos', function(err) {
// Подписались на всю коллекцию todos
});
model.subscribe('todos.e1b8075c-de9a-458a-aa3c-e9b383691521', function(err) {
// Подписались на один объект
});
model.subscribe('todos.e1b8075c-de9a-458a-aa3c-e9b383691521.text', function(err) {
// Подписались на одно поле одного объекта
});
model.subscribe('users', 'todos.e1b8075c-de9a-458a-aa3c-e9b383691521.text', function(err) {
// Можно кстати совмещать, чтобы не плодить колбэков
});
Suppose we are a very busy person and we have a million todos. And we want to subscribe only to those whose text contains certain characters. Why do we need the entire collection on the client? paths are useless here. filter too. Queries come to our aid:
app.get('/', function(page, model) {
var query = model.query('todos', {text: 'Todo 1'})
model.subscribe(query, function(err) {
if (!model.get('todos')) {
model.add('todos', {text: 'Todo 1'});
model.add('todos', {text: 'Todo 2'});
}
query.ref('_page.todos');
page.render();
})
});
{text: 'Todo 1'}
Is the Mongo Queries . That is, the livedb-mongo adapter forwards this object directly to mongo. For other databases, you can write your own adapters and do it somehow differently. Materials by Derby.js