Meteor 流星:收集助手还是FS.collection上的转换?

Meteor 流星:收集助手还是FS.collection上的转换?,meteor,meteor-helper,collectionfs,Meteor,Meteor Helper,Collectionfs,使用dburles:collection helpers包,您可以在任何Mongo.collection上添加集合帮助程序。但我不能在FS.Collection上这样做。我得到类型错误:对象[Object Object]没有方法“helpers”。转换函数也不起作用 var createUploader = function(fileObj, readStream, writeStream) { fileObj.uploadedBy = Meteor.users.find({_id: f

使用dburles:collection helpers包,您可以在任何Mongo.collection上添加集合帮助程序。但我不能在FS.Collection上这样做。我得到类型错误:对象[Object Object]没有方法“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.File
获取
userId
,因此
fileObj.uploadedBy=Meteor.users.find({u id:fileObj.uploader})

matb33集合帮助程序包通过对集合应用转换函数来工作。CollectionFS已经应用了自己的转换函数,因此不能使用collection helpers包中的函数覆盖该函数

正如在会议上所建议的那样

因为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();
  }
})

{{#使用FS.GetFile“Photos”photo}
{{/与}}
Template.somePhoto.helpers({
照片:功能(){
返回照片。findOne();
}
})

好的,我知道这不是我想要的那么简单的解决方案。因为我使用的是发布复合包。我可以用照片发布用户数据(仅个人资料字段)。在客户端上,我可以执行以下模板帮助程序:

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


{{{每张照片}
{{>照片}
{{/每个}}
...
然后


{{photoUploader}}
...

在CollectionFS文档中,表示通过myFSCollection.files提供的基础Mongo.Collection实例缺少该部分。但仍然得到错误:错误:[无法将帮助程序应用于'cfs.photos.filerecord'转换函数已存在!]我刚刚发现,这可能有助于将类似帮助程序的转换应用于collectionfs实例。我用现有代码编辑了我的问题,但代码无效。如何扩展FS.File原型?我可以看一下任何例子吗?我已经更新了答案,以反映您似乎正在寻求的元数据解决方案。很抱歉,我的答复太晚,我只有有限的时间和使用计算机。您的代码正在插入带有
userId
作为
uploadedBy
元数据的文件对象。我已经做到了。但是在fs集合中,我试图基于
userId
进行
转换,并获取用户数据(上传的数据)。像这样
fileObj.uploader=Meteor.users.find({u id:fileObj.uploadedBy});返回fileObj。因此,在模板上,我可以执行
uploader.profile.name
来获取用户的姓名而不是id。显然,我没有做到这一点。我添加了我自己的答案,效果很好。但我真的很想知道艰难的道路,并将进一步研究它。谢谢您的帮助。@Zaya我已经更新了答案,这样我们现在可以存储名称而不是用户ID,或者如果您愿意,可以同时存储这两个名称。
<template name="photos">
    {{#each photos}}
      {{> photo}}
    {{/each}}
    ...
<template name="photo">
  {{photoUploader}}
  ...