find
методът връща курсор, а не обект или масив. За достъп до обект трябва или да го извлечете от курсора
var skill = Skills.find(Session.get('selected_skill')).fetch()[0];
или го вземете директно с findOne
:
var skill = Skills.findOne(Session.get('selected_skill'));
След това можете да го използвате като всеки друг js обект:
console.log(skill.mana);
skill._cache = {cooldown: true};
Имайте предвид, че от страна на клиента, методи за събиране като find
са неблокиращи. Те връщат всичко, което Meteor има в кеша, не непременно това, което е в сървърната база данни. Ето защо винаги трябва да ги използвате в реактивен контекст или да се уверите, че всички данни са извлечени преди изпълнението (не се притеснявайте за последното, докато не владеете Meteor, започнете с първия начин).
Освен това трябва да имате предвид, че поради това findOne
и find.fetch
може да върне null
/ празен масив, дори когато съответният елемент е в db (но все още не е кеширан). Ако не вземете това предвид във вашите реактивни функции, ще попаднете на грешки.
Template.article.slug = function() {
var article = Articles.findOne(current_article);
if(!article) return '';
return slugify(article.title);
};
Ако не сме избягали от функцията с if(!article)
, изразът article.title
ще доведе до грешка при първото изчисление, като article
ще бъде недефиниран (ако приемем, че не е бил кеширан по-рано).
Когато искате да актуализирате базата данни от страна на клиента, можете да промените само един елемент по време и трябва да се обърнете към елемента чрез неговия _id
. Това се дължи на съображения за сигурност. Вашият ред за това беше добър:
Skills.update(Session.get('selected_skill'), {$inc: {mana: 1}});
alert()
е функция, която връща undefined без значение с какво го храните.
alert(42); // -> undefined
Като цяло е далечната по-добре да отстранявате грешки с console.log
отколкото с alert
.