Meteor:收集助手或转换FS.Collection?

时间:2015-10-30 20:27:13

标签: meteor meteor-helper collectionfs

使用dburles:collection-helpers包,您可以在任何Mongo.collection上添加集合助手。但我不能在FS.Collection上这样做。我得到 TypeError:对象[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({_id: fileObj.uploader});

2 个答案:

答案 0 :(得分:0)

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

根据issue tracker

的建议
  

由于CFS已经应用了转换,因此使用集合助手不是一个好主意。但是,通过使用自己的函数扩展FS.File原型,你应该可以做同样的事情。

您可以在原型上定义自定义函数。原型可以通过this访问doc的其他属性,因此您基本上可以使用集合助手来实现相同的功能。

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

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

答案 1 :(得分:0)

好的我知道这不是我想要的那么简单的解决方案。因为我使用的是发布复合包。我可以发布用户&#39;带照片的数据(仅限个人资料字段)。在客户端我可以像这样做模板助手:

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}}
  ...