Одна из основных проблем для новых программистов, изучающих Meteor.js, заключается в том, как работать с данными, поступающими с сервера MongoDB на клиент, объектно-ориентированным способом. Когда вы впервые начинаете изучать Meteor, не очевидно, как обернуть коллекцию (эквивалент Meteor «модели» в парадигме модель-представление-контроллер) в формат данных, с которым вы можете легко работать.
В стандартной среде MVC, такой как Rails, вам не нужно беспокоиться о создании собственных абстракций для более простой работы с данными, поступающими из серверной части в пользовательский интерфейс. Active Record сделает все за вас в Rails. В Meteor у нас нет эквивалентной встроенной абстракции. Стандартная функциональность Meteor делает слой модели довольно компактным и вместо этого использует простой JavaScript для представления документов MongoDB. Но еще не все потеряно! Ниже я объясню, как вы можете изменить необработанный вывод сервера для клиента с помощью встроенного метода преобразования Meteor.
Во-первых, я хотел бы начать с демонстрации общего способа обработки создания классов в JavaScript. Основная концепция, которую я собираюсь рассмотреть, — это наследование. Поскольку JavaScript — это язык, основанный на прототипах (в отличие от Ruby или Java, которые основаны на классах), в нем нет понятия классов как таковых. Мы можем объявить класс так же, как и функцию:
function Teletubby() {};
Правильное имя для этого классоподобного объекта в JavaScript — конструктор. Чтобы изменить свойства конструктора, вы должны сделать это через свойство конструктора с именем прототип:
function Teletubby() { // new constructor! } Teletubby.prototype.sayEhoh = function() { return "Eh-oh!"; }; var tinkyWinky = new Teletubby(); var laaLaa = new Teletubby(); tinkyWinky.sayEhoh(); // "Eh-oh!" laaLaa.sayEhoh(); // "Eh-oh!"
Теперь мы можем успешно создавать экземпляры новых телепузиков и заставлять их говорить Э-э-э! семантически значимым образом. Мы также можем перезаписать унаследованный метод sayEhoh() для каждого экземпляра нового объекта Teletubby, сохраняя при этом наш код чистым и организованным.
Как теперь добиться того же эффекта, работая в Meteor? Ответ таков: используя преобразование для добавления вычисляемых свойств, с которыми мы можем работать на стороне клиента, в наш объект Collection.
Во-первых, давайте создадим коллекцию для работы с:
lib/collections/teletubbies.js Teletubbies = new Mongo.Collection('teletubbies', { transform: function(doc) { return ( new Teletubby( doc ) ); } });
Теперь давайте опубликуем коллекцию клиенту через публикацию:
server/publications/publications.js Meteor.publish(‘teletubbies’ , function() { return ( Teletubbies.find() ); });
На клиенте Meteor предоставляет нам мини-базу данных Minimongo, которая принимает данные Collection с сервера по подписке (используя Meteor.subscribe):
lib/collections/teletubbies.js if (Meteor.isClient) { Meteor.subscribe(‘teletubbies’); }
Теперь давайте сразу приступим к трансформации. Вот объяснение этого свойства в документации Meteor:
Теперь мы можем добавить метод в нашу коллекцию через прототип следующим образом:
// doc is documents data coming from MongoDB Teletubby = function (doc) { _.extend(this, doc); }; _.extend(Teletubby.prototype, { sayEhoh: function () { return "Eh-oh!"; } });
Обратите внимание, что новый Mongo.Collection не создает новую таблицу в базе данных MongoDB. Вместо этого он создает объект, представляющий вашу коллекцию MongoDB (которая может уже существовать, а может и не существовать). Фактическая коллекция создается, когда вы вставляете такой объект документа в консоль браузера:
Teletubbies.insert({name: "tinkyWinky"}); Teletubbies.insert({name: "laaLaa"});
Теперь мы можем найти коллекцию на клиенте и вызвать для нее созданный нами метод:
Teletubbies.findOne({name: "tinkyWinky"}).sayEhoh(); // "Eh-oh!" Teletubbies.findOne({name: "laaLaa"}).sayEhoh(); // "Eh-oh!"
Вот как это выглядит в консоли:
Насколько мне известно, преобразование до сих пор не является распространенным способом манипулирования данными в приложениях Meteor. Хотя он недостаточно представлен, я думаю, что это отличный инструмент, который может помочь сделать ваш код более удобным для сопровождения и организованным в долгосрочной перспективе. Каково ваше мнение о трансформации? Это обычно используется в производстве или в настоящее время является новинкой?
Обратная связь очень ценится!