Подтвердить что ты не робот

Какой лучший способ приложить поведение к коллекции Метеор?

В Meteor, когда вы извлекаете запись из базы данных, это только запись. Поэтому, если у меня есть коллекция под названием Dogs, dog может иметь fur: 'brown' или breath: 'stinky', но у нее нет метода bark().

Очевидно, я мог бы создать некоторые функции, ожидающие a dog в качестве аргумента, а затем выполнить операции над этим dog. Я мог бы даже инкапсулировать все эти функции в один конструктор. Я не сумасшедший об этом подходе, но если кто-то получил чистый и разумный способ сделать это, я все уши.

Еще одна мысль о том, что я должен был обернуть dog в Backbone.Model. Это может быть интересно, так как fetch и save могут быть переопределены для выполнения find и insert или update, и вы также можете определить все свое поведение там, но я прочитал, что этот тип вещь обычно обескуражена.

Есть ли правильный способ сделать это? Есть ли Meteor.Model официально в работах? Как другие решают эту проблему?

Edit

Для тех, кто подходит к этому вопросу через год после принятого ответа: во время этого редактирования я использую Exygy minimongoid mrt package, который имеет некоторые улучшения haihappen version, которые упоминаются в сообщении в блоге, связанном с принятым ответом.

В настоящее время я вношу вклад в репозиторий, чтобы сделать результат более похожим на отношение. Надеемся, что другие получат от этого выгоду и почувствуют склонность вносить полезные функции.

Edit

Другой ответ предложил использовать свойство transform при создании коллекции. Хотя я определенно предпочитаю то, что мне действительно не нужно строить самостоятельно, эта функция добавляет много возможностей, и я надеюсь, что любые команды, которые работают над ORM для Meteor, воспользуются этим в своей основе.

Здесь сообщение в блоге, в котором объясняется, как использовать свойство transform.

Кроме того, minimongoid теперь доступен как пакет Meteor, и я все еще использую его. Он поддерживает проверку и декларирование отношений. Я добавил некоторые функциональные возможности для этого пакета, поэтому, если на плате много элементов, board.pieces().create(attributes) будет сохранять новую запись piece с данным attributes и будет автоматически ассоциироваться с board. Из различных решений, которые я видел, это кажется наиболее полным.

4b9b3361

Ответ 1

Хотя в работе может быть официальная модельная система, вы можете сделать следующее:

Есть один Марио Улер, который является activerecord, как и довольно приятным, в coffeescript: https://coderwall.com/p/_q9b1w

Существует также пакет сообщества, сделанный Томом Коулманом, который очень помогает с моделями: https://github.com/tmeasday/meteor-models, вам может понадобиться meteorite, чтобы добавить его в виде пакета.

И, конечно, как вы предложили Backbone. Я лично использую прототипы js, но не все могут быть с ними удобны, я просто использовал их, поэтому их легко перевести, когда система моделей метеоров отсутствует, ее также легко разделить между клиентом и сервером, не добавляя слишком много пакетов.

Ответ 2

Вы можете использовать параметр transform в коллекции для перегрузки объекта с помощью специальных функций

var Dogs = new Meteor.Collection("dogs", 
{
    transform:function(entry)
    {
        entry.bark = function(){ console.log(this.barkSound);};
        return entry;
    }
});

Тогда:

var aDogID = new Dogs.insert({barkSound: "ruff"})
Dogs.find(aDogID).bark(); // "ruff"

Бонус: Если по какой-либо причине вы хотели бы использовать аналогичную концепцию, предложенную Эндрю Ферком, просто используйте функцию _.defaults(object, * defaults).

var defaults = {
             barkSound: "ruff",
             bark: function() {
                        console.log(this.barkSound);
                    }
            }

Dogs = new Meteor.Collection("dogs",
        {
            transform: function(object) {
                return _.defaults(object, defaults);
            }
        });

Ответ 3

Это начало переопределения Meteor.Collection для поддержки методов объектов.

Meteor.Kollection = Meteor.Collection;
Meteor.Kollection.extend = function(constructor) {
  var parent = this;
  var child = function() {
    Meteor.Kollection.apply(this, arguments);
    constructor.apply(this, arguments);
  };

  _.extend(child, parent);

  function __proto__() { this.constructor = child; };
  __proto__.prototype = parent.prototype;
  child.prototype = new __proto__;

  return child;
};

Meteor.Collection = Meteor.Kollection.extend(function(name, options) {
  if (options && options.defaults) {
    this.defaults = options.defaults;
  }
});

Meteor.Collection.prototype.applyDefaults = function(attrs) {
  return _.defaults(attrs, this.defaults);
};

Meteor.Collection.prototype.create = function(attrs) {
  if (typeof attrs !== "object") attrs = {};
  return this.applyDefaults(attrs);
};

Meteor.Collection.prototype.findOne = function(selector, options) {
  var object = Meteor.Kollection.prototype.findOne.apply(this, arguments);
  return this.applyDefaults(object);
};

Вы можете заметить новый метод collection.create, и что collection.findOne был переопределен. Я предполагаю, что все методы коллекции. * Должны быть переопределены, но это начало.

Итак, что вы можете сделать с этим?

var Dogs = new Meteor.Collection("dogs", { defaults: {
  barkSound: "ruff",
  bark: function() {
    console.log(this.barkSound);
  }
}});

if (Meteor.isClient) {
  var regularDog = Dogs.create();
  regularDog.bark(); // ruff

  var smallDog = Dogs.create({
    barkSound: "yip"
  });
  smallDog.bark(); // yip

  Dogs.insert(smallDog, function(error, id) {
    Dogs.findOne(id).bark(); // yip
  });
});

Я не совсем уверен, как это происходит, но любые функции в объекте удаляются, когда они вставлены. Поэтому мы можем напрямую применить методы к объекту. Во-первых, вы создаете свою коллекцию, передавая объект с свойством defaults. Это свойство может включать свойства или методы. Чтобы создать новый объект для данной коллекции, используйте команду collection.create(attrs), где attrs - аргумент параметра, который включает дополнительные или переопределенные свойства и методы.

Ответ 4

Astronomy - это новый ответ на этот старый вопрос о моделях Метеор. У автора гораздо больше запланированных функций, которые находятся в работах и ​​поддержке других известных авторов метеорных пакетов. Единственный недостаток - возможно, это немного кровоточащий край.

Астрономия также высокомодулированная, яркий пример построения в стиле метеорного/модульного стиля.

Ответ 5

Это относительно старый вопрос с точки зрения Метеор, но я думаю, dburles: collection-helpers соответствует тому, что вы хотели достичь, реализуя то, что предложил Флавиен Фолькен. Возможно, это полезно для тех, кто недавно блуждал здесь.

Ответ 6

Дополнения к ответу @Flavien Volken вы можете передать аргументы методу, который вы добавили в коллекцию.

Car = new Mongo.Collection('car', {
    transform: function(entry) {
        entry.is_watched = function(userId) {
            var is_watched = false;
            if (entry.watchList) {
                for (var i in entry.watchList) {
                    if (entry.watchList[i].userId == userId) {
                        is_watched = true;
                        break;
                    }
                }
            }
            return is_watched;
        };
        return entry;
    }
});

В шаблоне (идентификатор прохода зарегистрированного пользователя):

{{# if is_watched currentUser._id }}
    Watched
{{ else }}
    Not watched
{{/ if }}