0

使用 dburles:collection-helpers 包,您可以在任何 Mongo.collection 上添加集合助手。但我不能在 FS.Collection 上这样做。我得到TypeError: Object [object Object] has no method 'helpers'。变换功能也不起作用。

var createUploader = function(fileObj, readStream, writeStream) {
    fileObj.uploadedBy = Meteor.users.find({_id: fileObj.uploader});
    readStream.pipe(writeStream);
};
Photos = new FS.Collection("photos", {
    stores: [
        new FS.Store.GridFS("photos", {transformWrite: createUploader})
    ],
    filter: {
        allow: {
            contentTypes: ['image/*']
        }
    }
});

不能这样做吗?请注意,当从客户端插入照片时FS.Fileget userId,因此fileObj.uploadedBy = Meteor.users.find({_id: fileObj.uploader});

4

2 回答 2

0

好的,我知道这不是我正在寻找的不太容易的解决方案。因为我使用的是发布复合包。我可以只发布带有照片的用户数据(仅限个人资料字段)。在客户端我可以像这样做模板助手:

Template.photo.helpers({
    photoUploader: function() {
        var currentPhoto = Photos.findOne();
        var user = Meteor.users.findOne({_id: currentPhoto.uploader});
        return user.profile.name;
    },
});

<template name="photos">
    {{#each photos}}
      {{> photo}}
    {{/each}}
    ...

然后

<template name="photo">
  {{photoUploader}}
  ...
于 2015-11-02T07:15:01.390 回答
0

matb33-collection-helpers 包通过将转换函数应用于集合来工作。CollectionFS 已经应用了自己的转换函数,因此您不能用集合助手包中的函数覆盖它。

正如问题跟踪器所建议的那样

由于 CFS 已经应用了转换,因此使用集合助手不是一个好主意。不过,您应该能够通过使用自己的函数扩展 FS.File 原型来做几乎相同的事情。

您可以在原型上定义自定义函数。原型将可以访问文档的其他属性,this因此您基本上可以使用与集合助手相同的功能。

另一种选择是在插入期间将文件相关信息存储在单个文件对象上作为元数据,例如:

Template.photoUploadForm.events({
  'change .photoInput': function(event, template) {
    FS.Utility.eachFile(event, function(file) {
      var newPhoto = new FS.File(file);
      newPhoto.metadata = {uploadedBy: Meteor.user().profile.name};
      Photos.insert(newPhoto, function (err, fileObj) {
        if (!err) console.log(fileObj._id + " inserted!")
      });
    });
  }
});

您的代码也可以重写以实现beforeWrite过滤器而不是 transformWrite ,如

Photos = new FS.Collection("photos", {
    stores: [
        new FS.Store.GridFS("photos", {
          beforeWrite: function (fileObj) {
            fileObj.metadata = {uploadedBy: Meteor.user().profile.name};
          }
        })
    ],
    filter: {
        allow: {
            contentTypes: ['image/*']
        }
    }
});

最后,您可以选择存储用户的 ID 并发布响应式联接

Photos = new FS.Collection("photos", {
    stores: [
        new FS.Store.GridFS("photos", {
          beforeWrite: function (fileObj) {
            fileObj.metadata = {
              uploadedBy: Meteor.userId()
            };
          }
        })
    ],
    filter: {
        allow: {
            contentTypes: ['image/*']
        }
    }
});

对于发布,您可以使用reywood:publish-composite

Meteor.publishComposite('photosWithUsers', function() {
  return {
    find: function() {
      return Photos.find();
    },
    children: [
      {
        find: function(photo) {
          return Meteor.users.find(photo.uploadedBy, {
            fields: {username: 1, 'profile.name': 1}
          });
        }
      }
    ]
  };
});

当然在客户端,你需要订阅photosWithUsers发布。

现在要在客户端访问该信息,因为您无法在 collectionFS 文档上应用转换或帮助程序,您可以创建一个全局模板帮助程序:

Template.registerHelper('getUsername', function(userId) {
  check(userId, String);
  var user = Meteor.users.findOne(userId);
  return user && user.profile.name + ' (' + user.username + ')';
});

现在您可以在模板中使用该助手:

<template name="somePhoto">
  {{#with FS.GetFile "Photos" photo}}
    <img src="{{url}}" alt="This photo has been uploaded by {{getUsername uploadedBy}}"> 
  {{/with}}
</template>

Template.somePhoto.helpers({
  photo: function() {
    return Photos.findOne();
  }
})
于 2015-11-01T14:23:27.710 回答