Нека направим разлика между различните имена, с които може да се наложи да се справите, когато програмирате Meteor:
- Имена на променливи , като
Posts = new Meteor.Collection(...)
. Те се използват само за да знае вашият код как да получи достъп до тази променлива. Meteor не знае или не го интересува какво е, въпреки че конвенцията е да се пише с главни букви. - Имена на колекции , като
new Meteor.Collection("posts")
. Това се съпоставя с името на колекция MongoDB (на сървъра) или колекция minimongo (на клиента). - Имена на публикации и абонаменти , използван в
Meteor.publish("foo", ...)
илиMeteor.subscribe("foo")
. Те трябва да съвпадат, за да може клиентът да се абонира за някои данни на сървъра.
Има две неща, които трябва да съпоставите в модела на данни Meteor:
- Имена на публикации и съответните им абонаменти
- (обикновено) Имена на колекции на клиента и сървъра, ако използвате модела на колекция по подразбиране
Името на абонамента трябва винаги да съвпада с името на публикация. Въпреки това, колекциите, които се изпращат за даден абонамент, не трябва да имат нищо общо с името на абонамента. Всъщност човек може да изпрати надмножество курсора в една публикация или една колекция върху различни публикации или дори множество абонамента на публикация , които изглеждат обединени като едно в клиента. Можете също да имате различни имена на колекции в сървъра и клиента; четете нататък...
Нека разгледаме различните случаи:
-
Прост модел на абонамент . Това е този, който обикновено виждате в обикновените демонстрации на Meteor.
На клиент и сървър,
Posts = new Meteor.Collection("posts");
Само на сървъра:
Meteor.publish("postsPub", function() { return Posts.find() });
Само за клиент:
Meteor.subscribe("postsPub")
Това синхронизира
Posts
колекция (която се наричаposts
в базата данни) с помощта на публикацията, нареченаpostsPub
. -
Множество колекции в една публикация . Можете да изпратите множество курсори за една публикация, като използвате масив.
На клиент и сървър:
Posts = new Meteor.Collection("posts"); Comments = new Meteor.Collection("comments");
Само на сървъра:
Meteor.publish("postsAndComments", function() { return [ Posts.find(), Comments.find() ]; });
Само за клиент:
Meteor.subscribe("postsAndComments");
Това синхронизира
Posts
колекция, както иComments
колекция с помощта на една публикация, нареченаpostsAndComments
. Този тип публикация е много подходяща за релационни данни; например, където може да искате да публикувате само определени публикации и коментарите, свързани само с тези публикации. Вижте пакет, който може да изгради тези курсори автоматично . -
Множество публикации за една колекция . Можете да използвате множество публикации, за да изпращате различни части от данни за една колекция, които се обединяват автоматично от Meteor.
На сървър и клиент:
Posts = new Meteor.Collection("posts");
Само на сървъра:
Meteor.publish("top10Posts", function() { return Posts.find({}, { sort: {comments: -1}, limit: 10 }); }); Meteor.publish("newest10Posts", function() { return Posts.find({}, { sort: {timestamp: -1}, limit: 10 }); });
Само за клиент:
Meteor.subscribe("top10Posts"); Meteor.subscribe("newest10Posts");
Това изпраща както 10-те публикации с най-много коментари, така и 10-те най-нови публикации в сайта към потребителя, който вижда и двата набора данни, обединени в един
Posts
колекция. Ако една от най-новите публикации е и публикация с най-много коментари или обратно,Posts
колекцията ще съдържа по-малко от 20 артикула. Това е пример за това как моделът на данни в Meteor ви позволява да извършвате мощни операции за сливане на данни, без да прилагате сами подробностите. -
Няколко абонамента на публикация. Можете да получите множество набори от данни от една и съща публикация, като използвате различни аргументи.
На сървър и клиент:
Posts = new Meteor.Collection("posts");
Само на сървъра:
Meteor.publish("postsByUser", function(user) { return Posts.find({ userId: user }); });
Само за клиент:
Meteor.subscribe("postsByUser", "fooUser"); Meteor.subscribe("postsByUser", "barUser");
Това причинява публикациите от
fooUser
иbarUser
и двете да се показват вposts
колекция. Този модел е удобен, когато имате няколко различни изчисления, които разглеждат различни части от вашите данни и може да се актуализират динамично. Имайте предвид, че когато се абонирате вDeps.autorun(...)
, Meteor извикваstop()
на всяка предишна дръжка на абонамента със същото име автоматично, но ако използвате тези абонаменти извънautorun
ще трябва да ги спрете сами. Към момента не можете да правите два абонамента с едно и също име вautorun
изчисление, защото Meteor не може да ги различи. -
Пускане на произволни данни върху публикация. Можете напълно да персонализирате публикациите, така че да не изискват едни и същи имена на колекции на сървъра и клиента. Всъщност сървърът може да публикува данни, които изобщо не са подкрепени от колекция. За да направите това, можете да използвате API за функциите за публикуване .
Само на сървъра:
Posts = new Meteor.Collection("posts"); Meteor.publish("newPostsPub", function() { var sub = this; var subHandle = null; subHandle = Posts.find({}, { sort: {timestamp: -1}, limit: 10 }) .observeChanges({ added: function(id, fields) { sub.added("newposts", id, fields); }, changed: function(id, fields) { sub.changed("newposts", id, fields); }, removed: function(id) { sub.removed("newposts", id); } }); sub.ready(); sub.onStop(function() { subHandle.stop(); }) });
Само за клиент:
NewPosts = new Meteor.Collection("newposts"); Meteor.subscribe("newPostsPub");
Това синхронизира най-новите 10 публикации от
Posts
колекция на сървъра (нареченаposts
в базата данни) къмNewPosts
колекция на клиента (нареченаnewposts
в minimongo) с помощта на публикацията/абонамента, нареченаnewPostsPub
. Обърнете внимание, чеobserveChanges
се различава отobserve
, който може да прави куп други неща.Кодът изглежда сложен, но когато върнете курсор вътре в функция за публикуване, това е основно кодът, който Meteor генерира зад кулисите. Писането на публикации по този начин ви дава много повече контрол върху това какво се изпраща и какво не се изпраща на клиента. Все пак бъдете внимателни, тъй като трябва ръчно да изключите
observe
дръжки и маркирайте кога абонаментът е готов. За повече информация вижте описанието на Мат Дебергалис за този процес (но тази публикация е остаряла). Разбира се, можете да комбинирате това с другите части по-горе, за да получите потенциално много нюансирани и сложни публикации.
Съжалявам за есето :-) но много хора се объркват за това и смятам, че би било полезно да опиша всички случаи.