【问题标题】:Publish not updating properly?发布没有正确更新?
【发布时间】:2012-12-29 16:39:23
【问题描述】:

我无法让Meteor.publish 更新以响应不断变化的表单字段。对发布的第一次调用似乎坚持,所以查询在该子集中运行,直到重新加载页面。

我遵循this post 中的方法,但没有任何运气。

非常感谢任何帮助。

在库中:

SearchResults = new Meteor.Collection("Animals");

function getSearchResults(query) {
  re = new RegExp(query, "i");
  return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
}

在客户端:

Session.set('query', null);

Template.searchQuery.events({
  'keyup .query' : function (event, template) {
    query = template.find('.query').value
    Session.set("query", query);
  }
});

Meteor.autosubscribe(function() {
  if (Session.get("query")) {
    Meteor.subscribe("search_results", Session.get("query"));
  }
});

Template.searchResults.results = function () {
  return getSearchResults(Session.get("query"));
}

在服务器上:

Meteor.publish("search_results", getSearchResults);

模板: 寻找动物

<body>
  {{> searchQuery}}

  {{> searchResults}}
</body>

<template name="searchQuery">
  <form>
  <label>Search</label>
  <input type="text" class="query" />
</form>
</template>

<template name="searchResults">
  {{#each results}}
  <div>
    {{_id}}
  </div>
  {{/each}}
</template>

更新[错误]

显然,问题在于我正在使用的集合(正确)是在 Meteor 之外生成的,但 Meteor 不能正确支持 Mongo 的 ObjectId。 上下文 hererelated Stackoverflow question

此处显示转换代码,由antoviaque提供:

db.nodes.find({}).forEach(function(el){
    db.nodes.remove({_id:el._id}); 
    el._id = el._id.toString(); 
    db.nodes.insert(el); 
});

更新[右]

事实证明,这是RegExp / $regex 的问题。 This thread 解释。而不是:

function getSearchResults(query) {
  re = new RegExp(query, "i");
  return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
}

目前,需要这样做:

function getSearchResults(query) {
  // Assumes query is regex without delimiters e.g., 'rot'
  // will match 2nd & 4th rows in Tim's sample data below
  return SearchResults.find({$and: [ {is_active: true}, {id_species: {$regex: query, $options: 'i'}} ] }, {limit: 10});
}

这很有趣。

PS -- ddp-pre1 branch 有一些 ObjectId 功能 (SearchResults = new Meteor.Collection("Animals", {idGeneration: "MONGO"});)

【问题讨论】:

    标签: meteor


    【解决方案1】:

    这是我的工作示例:

    UPDATE 给出的原始 javascript 是正确的。正如 cmets 中指出的那样,问题原来是 meteor doesn't yet support ObjectIds

    HTML:

    <body>
      {{> searchQuery }}
      {{> searchResults}}
    </body>
    
    <template name="searchQuery">
      <form>
      <label>Search</label>
      <input type="text" class="query" />
    </form>
    </template>
    
    <template name="searchResults">
      {{#each results}}
      <div>
         {{id_species}} | {{name}} - {{_id}}
      </div>
      {{/each}}
    </template>
    

    Javascript:

    Animals = new Meteor.Collection("Animals");
    
    function _get(query) {
        re = new RegExp(query, "i");
        console.log("rerunning query: " + query);
        return Animals.find({$and: [ {is_active: true}, {id_species: {$regex: re}} ] }, {limit: 10});
    };
    
    if (Meteor.isClient) {
    
        Session.set("query", "");
    
        Meteor.autosubscribe(function() {
            Meteor.subscribe("animals", Session.get("query"));
        });
    
        Template.searchQuery.events({
          'keyup .query' : function (event, template) {
            query = template.find('.query').value
            Session.set("query", query);
          }
        });
    
        Template.searchResults.results = function () {
            return _get(Session.get("query"));              
        }
    }
    
    if (Meteor.isServer) {
        Meteor.startup(function() {
            if (Animals.find().count() === 0) {
                Animals.insert({name: "panda", is_active: true, id_species: 'bear'});
                Animals.insert({name: "panda1", is_active: true, id_species: 'bearOther'});
                Animals.insert({name: "panda2", is_active: true, id_species: 'bear'});
                Animals.insert({name: "panda3", is_active: true, id_species: 'bearOther'}); 
            }
        });
        Meteor.publish("animals", _get);
    }
    

    【讨论】:

    • 蒂姆,感谢您的回复。上面的主要变化(除了组合文件)似乎是从服务器端删除查询选择器。如果我没记错的话,这具有发布整个集合的效果,即就像我打开了自动发布一样。不幸的是,Animals 集合中大约有 500k 文档(集合名称已更改以保护无辜者)。这种方法不会让我的浏览器崩溃吗?
    • 哦,谢谢你的澄清。好的。我修改了我原来的例子。你的第一个刺实际上比我意识到的要近 :) 你能告诉我这与你更大的记录集看起来如何吗?
    • 感谢您的跟进 - 刚刚尝试过。结果是一样的(实际上有点糟糕,因为查询为空的检查已经消失,所以它返回前 10 条记录和一个空白查询)。我不确定为什么上面的代码会产生任何不同,因为现在唯一的变化似乎是将 getSearchResults 重命名为 _get 并从发布中间接调用该函数。我敢肯定这很神奇,但此刻 Meteor 让我发疯了!
    • 现在我重写了它,它看起来和你的非常相似 :) 我在我的 _get 函数中添加了一个 console.log 行,并且它正在重新运行每次我发布函数keyup 在浏览器中。你没有看到同样的东西吗?
    • 我这样做了:Meteor.publish("search_results", function(q) { console.log("Publish query is: " + q); result = _get(q); console.log("Publish result count is: " + result.count()); return result; }); - 查询计数返回正确的值,但模板中的结果列表没有刷新。会不会像模板错误一样简单?
    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多