...

среда, 2 октября 2013 г.

Derby.js TODO or not TODO


Одни программисты уже осознали открывающиеся перспективы и взялись за изучение Derby. Другие, с интересом наблюдают за происходящим, но не готовы в данный момент расстаться с их любимым фреймворком по разным причинам. Третьи минусуют Derby-туториалы, полагая, что это как-то остановит прогресс и надвигающуюся волну full-stack фреймворков.


Ну а наш паровоз набирает ход и сегодня мы углубимся в наших Derby-изысканиях.


Настраиваем окружение и создаем bare-проект.


/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();
});


Здесь мы подписались на всю коллекцию todos. В дальнейшем все наши манипуляции с данными мы будем делать именно после того, как мы на них подписались, потому что до subscribe, наша модель пустая. Теперь добавляем пару объектов туда, если такой коллекции нету.

model.add — это обвертка над model.set. Единственное что она делаем, это генерирует ид сама. Мы могли бы написать так:



var id = model.id(); //так генеририруется guid с помощью require('node-uuid').v4()
model.set('todos.' + id, {text: 'Todo 1'});


Наша коллекция — это js-объект. Если сделать model.get('todos'), то получим:



{
"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"
}
}


Это хорошо для того, если мы хотим доставать из нее объекты по ид:



var todo = model.get('todos.e1b8075c-de9a-458a-aa3c-e9b383691521');


Но если мы хотим вывести наши todos в html, то нам бы лучше массив. Знакомьтесь, у нас есть замечательная штука — 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



<Body:>
{#each _page.todos as :todo}
<p>{:todo.text}</p>
{/}


Здесь мы создаем фильтр для todos. Он динамически следит за изменениями этой коллекции и выводит результат в '_page.todos' с помощью refList, о котором чуть позже. Но фильтр не был бы фильтром, если бы не умел фильтровать. Мы можем делать например вот так:



var todos = model.filter('todos', function(todo) {
return todo.text == 'Todo1';
}).get();


Здесь мы сразу извлекли отфильтрованный массив.



var todos = model.filter('todos').sort('text').get();


А тут мы еще и сделали сортировку по полю text.

Ни filter, ни sort не знают ничего про вашу бд. Они оперируют только данными, которые есть в модели. Заполняйте модель перед этим!


Дак что там с refList? Это так называемые references. Позволяют связывать данные между двумя path. Использовать на прямую их приходится редко, но их используют, например, filter и 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 — это список ид тех todo, которые мы хотим получить в результате. Также они задают очередность в массиве '_page.todos'. Мы можем менять '_page.ids' и это сразу отразится на '_page.todos'.


Давайте помучаем 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) {
// Можно кстати совмещать, чтобы не плодить колбэков
});


Допустим мы сильно занятый человек и у нас миллион todos. И мы хотим подписаться только не те, текст которых содержит определенные символы. Зачем нам вся коллекция на клиенте? paths тут безполезын. filter тоже. Нам на помощь приходят Queries:



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'} — это Mongo Queries. То есть livedb-mongo адаптер пробрасывает этот объект напрямую в монго. Для других баз данных можно написать свои адаптеры и делать это как-то по другому.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends:



Комментариев нет:

Отправить комментарий