【问题标题】:Get Meteor collection by name按名称获取 Meteor 集合
【发布时间】:2012-06-14 14:09:21
【问题描述】:

假设我写:

new Meteor.Collection("foos");
new Meteor.Collection("bars");

是否有用于按名称访问这些集合的 API?类似于Meteor.Collection.get(name),其中name"foos""bars"?我知道我可以写类似的东西

var MyCollections = {
    foos: new Meteor.Collection("foos");
    bars: new Meteor.Collection("bars");
}

然后使用MyCollections[name],但如果存在,我更愿意使用现有的 API。

【问题讨论】:

    标签: meteor


    【解决方案1】:

    与其看,我一直在做:

    Foos = new Meteor.Collection("foos");
    

    或者可能把它放在另一个对象中。我还没有真正制作 Collections 集合对象。

    【讨论】:

    • 好吧,我知道我能做到。但是我有大量的集合共享相同的代码,所以我想按名称引用它们。
    【解决方案2】:

    据我在collection.js 源中看到的,一旦它已经在服务器上初始化,API 目前无法按名称获取现有集合。添加该功能可能并不难。

    那么,为什么不分叉 Meteor 并提交补丁或创建一个智能包并分享它,我敢肯定还有其他人想要相同的功能。

    【讨论】:

    • 接受这个答案,因为它基于 the source 的阅读。
    • Meteor.connection._mongo_livedata_collections找到它
    • @nepjua 不是正确的集合,尝试在 javascript 控制台中插入它,您会看到数据确实插入到客户端但没有发送到服务器。跨度>
    • 这个答案已经过时了:现在有办法,至少在客户端。看到这个答案:stackoverflow.com/a/37938322/14637
    【解决方案3】:

    注意它们有一个返回值,所以你可以这样做

    var Patterns = new Meteor.Collection("patterns");
    

    并使用Patterns无处不在

    并且当您需要订阅服务器更新时,请将"patterns" 提供给Meteor.subscribe()


    如果您对多个集合有相同的代码,那么从软件工程的角度来看,您做错了什么的可能性很高;为什么不使用带有 type 字段的单个集合(或其他区分文档的内容)并使用它而不是使用多个集合?

    【讨论】:

    • 很高兴指出 OP 中似乎明显的遗漏,new Mongo.Collection 调用返回一个集合对象。另一方面,如果发布函数使用不同的名称,则仅向Meteor.subscribe() 提供集合名称可能不起作用。详情请见Understanding Meteor publish/subscribe
    【解决方案4】:
    var bars = new Meteor.Collection("foos");
    

    根据collection.js 所做的判断,我们用来实例化集合对象的行打开了与数据库的连接,并查找与我们提供的名称匹配的集合。因此,在这种情况下,建立了一个连接,并且集合“foos”被绑定到 Meteor.Collection 对象“bars”。请参阅 mongo-livedata 包中的 collection.jsremote_collection_driver.js

    与 MongoDB 一样,尽管您可以,但您不必显式创建集合。如 MongoDB 文档中所述:

    在插入第一个文档时会创建一个集合。

    所以,我认为你所追求的就是你已经拥有的——除非我完全误解了你的意图。

    【讨论】:

      【解决方案5】:

      正如其他人所提到的,如果不在创建时保存它,似乎没有办法获取包装的 Meteor.Collection 对象。

      但至少有一种方法可以列出所有创建的集合,并实际访问相应的 Mongo LocalCollection 对象。它们可从任何 Meteor Collection 对象中获得,因此为了保持通用性,您可以为此创建一个虚拟集合。使用这样的方法(CoffeeScript):

      dummy = new Meteor.Collection 'dummy'
      getCollection = (name) ->
        dummy._driver.collections[name]
      

      这些对象确实有所有的 find、findOne、update 等方法,甚至还有一些 Meteor 似乎没有公开的方法,比如看起来很有趣的 pauseObservers 和 resumeObservers。但我没有尝试直接摆弄这个 mongo LocalCollection 引用来了解它是否会相应地更新服务器集合。

      【讨论】:

      【解决方案6】:

      您始终可以推出自己的自动收集吸气剂。

      假设您有几个名为“Businesses”和“Clients”的集合。将每个引用放入一些“集合”对象并注册一个 Handlebars 助手以通过集合[“名称”]访问这些“集合”。

      即把这样的东西放在客户端main.js

      collections = collections || {};
      collections.Businesses = Businesses;
      collections.Clients = Clients;
      
      Handlebars.registerHelper("getCollection", function(coll) {
        return  collections[coll].find();
      });
      

      然后在您的 HTML 中,只需按名称引用集合:

      {{#each getCollection 'Businesses'}}
        <div> Business: {{_id}} </div>
      {{/each}}
      
      {{#each getCollection 'Clients'}}
        <div> Client: {{_id}} </div>
      {{/each}}
      

      看,不再需要通用的“列出所有记录”样板 js!

      【讨论】:

        【解决方案7】:

        基于 Shane Donelley 的 mongoinspector https://github.com/shanedonnelly1/mongoinspector

        getCollection = function (string) {
        for (var globalObject in window) {
            if (window[globalObject] instanceof Meteor.Collection) {
                if (globalObject === string) {
                    return (window[globalObject]);
                    break;
                };        
            }
        }
        return undefined; // if none of the collections match
        };
        

        【讨论】:

        • 你可以在服务器上做同样的事情,使用 this 而不是 window .代码相同,只需将window替换为this即可从全局命名空间中获取集合对象。
        • 在全局上下文之外,在严格模式下,使用var globals = Function('return this')(); 获取对全局对象的引用。所以将代码中的window替换为globals
        • 此模式由meteor-autocomplete使用。
        • 我不明白为什么你循环window对象而不是做:getCollection = function (string) { return (window &amp;&amp; window[string] &amp;&amp; window[string] instanceof Meteor.Collection) ? window[string] : undefined; }
        【解决方案8】:

        我刚刚找到了那个包:https://github.com/dburles/mongo-collection-instances/

        它可以让你

        Foo1 = new Mongo.Collection('foo'); // local
        Foo2 = new Mongo.Collection('foo', { connection: connection });
        
        Mongo.Collection.get('foo') // returns instance of Foo1
        
        Mongo.Collection.get('foo', { connection: connection }); 
        // returns instance of Foo2
        

        希望对你有帮助

        【讨论】:

        • 注意,这个包不再需要,因为现在检索现有集合是一个内置功能。
        • @malhal 你有链接显示,如何在当前版本中做到这一点?
        【解决方案9】:

        此功能于 2016 年 2 月添加到 Meteor:"Provide a way to access collections from stores on the client"

        它是这样工作的:

        Meteor.connection._stores['tasks']._getCollection();

        我使用它如下使用javascript控制台测试插入:

        Meteor.connection._stores['tasks']._getCollection().insert({text:'test'});

        对于插入,它需要insecure 包仍被安装,否则会收到拒绝访问消息。

        【讨论】:

        • 是否可以从服务器端和客户端调用它?我试过这段代码,总是得到 TypeError: Cannot read property '_stores' of undefined 在服务器端。
        【解决方案10】:

        使用https://github.com/dburles/mongo-collection-instances,您可以使用Mongo.Collection.get('collectionname')

        请注意,您插入的参数与创建集合时使用的参数相同。所以如果你使用const Products = new Mongo.Collection('products'),那么你应该使用get('products')(小写)。

        【讨论】:

          猜你喜欢
          • 2014-03-03
          • 2016-09-08
          • 1970-01-01
          • 1970-01-01
          • 2013-08-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多