如何改造'通过Meteor.publish返回的数据?

时间:2014-01-03 01:45:54

标签: meteor

Meteor Collections具有transform能力,允许将行为附加到从mongo返回的对象。

我们希望关闭自动发布,以便客户端无法访问数据库集合,但我们仍然需要转换功能。

我们使用更明确的Meteor.publish / Meteor.subscribe或RPC机制(Meteor.call()/ Meteor.methods())向客户端发送数据

我们怎样才能让Meteor客户端自动应用直接使用Meteor.Collection方法检索数据时的转换?

5 个答案:

答案 0 :(得分:12)

虽然您无法直接使用转换,但有一种方法可以在发布数据库查询之前转换数据库查询的结果。这就是“发布集合的当前大小”示例描述here

我花了一段时间才弄清楚一个非常简单的应用程序,所以也许我的代码也会帮助你:

Meteor.publish("publicationsWithHTML", function (data) {
    var self = this;
    Publications
        .find()
        .forEach(function(entry) {
            addSomeHTML(entry);  // this function changes the content of entry
            self.added("publications", entry._id, entry);
        });
    self.ready();
});

在客户端,您订阅了这个:

Meteor.subscribe("publicationsWithHTML");

但是你的模型仍然需要创建一个名为'publications'的集合(两边):

Publications = new Meteor.Collection('publications');

请注意,这不是一个很好的例子,因为它不能保持反应性。但我发现计数示例起初有点令人困惑,所以也许你会发现它有用。

答案 1 :(得分:8)

(Meteor 0.7.0.1) - meteor允许将行为附加到通过pub / sub返回的对象。

这是我提交给流星项目的拉取请求。

Todos = new Meteor.Collection('todos', {
// transform allows behavior to be attached to the objects returned via the pub/sub communication.
      transform : function(todo) {
          todo.update = function(change) {
             Meteor.call('Todos_update', this._id, change);
          },
          todo.remove = function() {
             Meteor.call('Todos_remove', this._id);
          }
         return todo;
     }
});
todosHandle = Meteor.subscribe('todos');

通过'todos'主题返回的任何对象都将具有update()和remove()函数 - 这正是我想要的:我现在将行为附加到返回的数据。

答案 2 :(得分:7)

尝试:

let transformTodo = (fields) => {
  fields._pubType = 'todos';
  return fields;
};

Meteor.publish('todos', function() {
  let subHandle = Todos
    .find()
    .observeChanges({
      added: (id, fields) => {
        fields = transformTodo(fields);
        this.added('todos', id, fields);
      },
      changed: (id, fields) => {
        fields = transformTodo(fields);
        this.changed('todos', id, fields);
      },
      removed: (id) => {
        this.removed('todos', id);
      }
    });
  this.ready();
  this.onStop(() => {
    subHandle.stop();
  });
});

答案 3 :(得分:2)

目前,您无法在服务器上将变换应用于已发布的集合。有关详细信息,请参阅this问题。这使您无论是在客户端上转换数据还是使用流星方法。在方法中,您可以让服务器对数据执行任何操作。

在我的一个项目中,我们通过方法调用执行最昂贵的查询(它连接多个集合,对文档进行非规范化,并修剪不必要的字段)。它没有被动反应,但它大大简化了我们的代码,因为所有的转换都发生在服务器上。

答案 4 :(得分:0)

使用peerlibrary:reactive-publish

扩展@Christian Fritz答案,使用Reactive Solution
Meteor.publish("todos", function() {
  const self = this;
  return this.autorun(function(computation) {

    // Loop over each document in collection 

     todo.find().forEach(function(entry) {

    // Add function to transform / modify each document here

      self.added("todos", entry._id, entry);
    });
  });
});