更改公开的集合字段值

时间:2014-07-22 13:56:32

标签: meteor

希望我的第一个问题不是一个愚蠢的问题。 让我们说我们想与meteor一起构建一个聊天应用程序,包括logedin和匿名用户。聊天应该像这样填写:

var post = {
   userId: user._id,                 // is empty if anonymous user
   submitted: new Date().getTime(),
   text: chat_message
   });

var postId = Posts.insert(post);

该出版物可能看起来像是为了确保不转移userId

Meteor.publish('getTheChat', function() {
  return Post.find({}, {fields: {userId: false});
});

但是有没有办法动态地在返回的集合中添加字段? 不应发布userId,而应发布"Your_Post""another_logedin_user""an_anonymous_user"等状态。通过这个,我可以包含一些CSS,所以聊天看起来更像WhatsApp或iMessage。

发布方法中的逻辑可能类似于

if (userId == this.userId) {
   status = "Your_Post";
} else if (userId != null) {
   status = "another_logedin_user";
} else {
   status = "an_anonymous_user";
}

您会发现,从不同用户调用时,发布应包含不同的值。 Meteor.publish中有没有办法?

感谢您的任何见解或建议

3 个答案:

答案 0 :(得分:1)

谢谢你们的想法!但是,由于我必须找出(仅仅为了我内心的平静)在发布方法服务器方面的可行性,我在David的链接的帮助下,来到了这个解决方案 - 可能它会帮助某人以后:

Meteor.publish('getTheChat', function(postId) {
  var currentUserId = this.userId;
  var ownerUserId = Posts.findOne({'_id':postId}).userId;
  var findOptions = {};   // in my final coding these differ for 'chat room owners' and 'normal users'

  var transform = function(post) {
    if (currentUserId && post.userId == currentUserId) {
      post.userId = "posted by you";    
    } else if (post.userId == null) {
      post.userId = "anonym posted";
    } else if (post.userId == ownerUserId) {
      post.userId = "posted by owner";
    } else {
      post.userID = "posted by another loged in";

    return post;
  }; 

  var self = this;

  var handle = Posts.find(findOptions).observe({
    added: function (document) {
      self.added('posts', document._id, transform(document));
    },
    changed: function (newDocument, oldDocument) {
      self.changed('posts', document._id, transform(newDocument));
    },
    removed: function (oldDocument) {
      self.removed('posts', oldDocument._id);
    }
  });

  self.ready();

  self.onStop(function(){
    handle.stop();
  });

通过这个我终于能够动态覆盖值。

答案 1 :(得分:0)

可悲的是,this has been a huge issue for me too,我很遗憾地说,在技术上不可能只在发布商的查询中添加字段,并在您的视图中方便地使用它。但是,我有一个可能对你有用的解决方案。一旦你想在Meteor中保留一些被动数据,它就会让你知道它会变得多么复杂。

服务器端:

首先,创建两个不同的发布者:一个用于当前用户的帖子,一个用于所有其他发布者:

Meteor.publish('getTheOthersChat', function() {
  return Post.find({$ne:{userId: this.userId}}, {fields: {userId: false});
});

Meteor.publish('getTheOwnChat', function() {
  return Post.find({userId: this.userId});
});

客户端/路由器端:

然后,订阅这两个:这将做什么只包括帖子的userId,只有当它是自己用户的id时。如果没有,它将是未定义的。

然后,我们仍然需要识别案例"匿名发布" vs"由用户发布"。为此,您可以在创建帖子期间添加其他字段,例如is_anonymous,然后根据用户是否登录的情况设置为truefalse。然后检查将是:

if (userId) {
   status = "Your_Post";
} else if (is_anonymous === false) {
   status = "another_logedin_user";
} else {
   status = "an_anonymous_user";
}

此解决方案应该有效。我知道,这是可悲的要来这种方式。它使Meteor看起来很笨重而且不切实际的任务应该很容易。这样一个很酷的框架真是太遗憾了!

答案 2 :(得分:0)

您似乎需要在Posts集合上添加转换。您可以在发布函数(as seen here)中执行此操作,但服务器端转换在计算上效率低下并且难以编写。虽然在只有服务器可以执行操作的情况下它们是必需的 - 例如签名的URL。在您的情况下,我建议使用标准集合转换,它是在提取文档后应用的过滤器。

不幸的是,这种转换需要客户端上的userId。我从未见过只是发布id会导致安全问题的情况。如果你认为这是你的应用程序的情况,我很有兴趣知道为什么。如果你能克服这个限制,继续阅读......

您可以在collections上的文档中阅读有关变换的内容,您可以在evented mind上看到示例。就个人而言,我喜欢使用collection-helpers包。

如果您尝试收集助手,您的转换可能如下所示:

Posts.helpers({
  status: function() {
    if (this.userId === Meteor.userId()) {
      return 'Your_Post';
    } else if (this.userId != null) {
      return 'another_logedin_user';
    } else {
      return 'an_anonymous_user';
    }
  }
});

然后你可以在你的模板中使用它,如:

{{#each posts}}
  <p>{{text}} - <span class='status'>{{status}}</span></p>
{{/each}}

当然,您也可以使用模板助手来获得相同的结果,但转换更容易在您的应用程序中重复使用。