Meteor在更新集合时发生异常,导致客户端反应性中断。

4
当我从前端调用 Collection.update 时(该方法调用是允许的),更新可以正常工作,但是下面的异常被抛出(在 Chrome 的 JS 控制台中,而不是在服务器上)。尽管更新已经发生,但是连接到同一集合的其他客户端直到刷新浏览器才能看到更新 - 我怀疑是因为异常的原因。
你有什么想法会导致这种情况发生?
Exception from Meteor.flush: Error: Can't create second landmark in same branch
    at Object.Spark.createLandmark (http://checkadoo.com/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:1085:13)
    at http://checkadoo.com/packages/templating/deftemplate.js?7f4bb363e9e340dbaaea8d74ac670af40ac82d0a:115:26
    at Object.Spark.labelBranch (http://checkadoo.com/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:1030:14)
    at Object.partial [as list_item] (http://checkadoo.com/packages/templating/deftemplate.js?7f4bb363e9e340dbaaea8d74ac670af40ac82d0a:114:24)
    at http://checkadoo.com/packages/handlebars/evaluate.js?ab265dbab665c32cfd7ec343166437f2e03f1a54:349:48
    at Object.Spark.labelBranch (http://checkadoo.com/packages/spark/spark.js?8b4e0abcbf865e6ad778592160ec3b3401d7abd2:1030:14)
    at branch (http://checkadoo.com/packages/handlebars/evaluate.js?ab265dbab665c32cfd7ec343166437f2e03f1a54:308:20)
    at http://checkadoo.com/packages/handlebars/evaluate.js?ab265dbab665c32cfd7ec343166437f2e03f1a54:348:20
    at Array.forEach (native)
    at Function._.each._.forEach (http://checkadoo.com/packages/underscore/underscore.js?772b2587aa2fa345fb760eff9ebe5acd97937243:76:11) 

编辑2

如果在控制台中运行更新调用,也会出现该错误。这个错误会在第一次更新时发生,但此时响应性已经在任何其他连接的浏览器上被破坏。

编辑 这是我的可点击项模板,触发更新:

<template name="list_item">
  <li class="checklistitemli">
  <div class="{{checkbox_class}}" id="clitem_{{index}}">
    <input type="checkbox" name="item_checked" value="1" id="clcheck_{{index}}" class="checklist_item_check" {{checkbox_ticked}}> {{title}}
  </div>
  </li>
</template>

以下是“list_item”点击事件的处理程序:

Template.list_item.events = {
  'click .checklistitem' : function(ev) {
    this.checked = !this.checked; 
    var updateItem = {}; 
    updateItem['items.'+this.index+'.checked'] = this.checked; 
    console.log("The error happens here");
    Lists.update({_id: this._id}, {$set:updateItem}, {multi:false} , function(err) { 
      console.log("In callback, after the error"); 
    });
  }
}

整个项目可以在http://checkadoo.com 找到(这是我基于Tornado框架开发的Python应用程序的端口)。

1
我猜问题不在于缺少关闭的 </input> 标签? - Tom Coleman
2
基于我对这个问题的模糊理解(它与 https://github.com/meteor/meteor/issues/281 有关),我认为如果没有看到 list_item 被调用的上下文,很难帮助解决这个问题。 - David Glasser
1
我也遇到了这个问题。这里有一个简单的应用程序可以展示它:https://gist.github.com/drew-gross/6202629 要重现,请在控制台上创建一个选项卡,输入 Tabs.insert({ owner:"foo" }),然后访问localhost:3000/tabs/:id,然后单击“购买一个”按钮。 - Drew
可能是重复的问题,参考链接:https://dev59.com/NG_Xa4cB1Zd3GeqP5dby - Stephan Tual
1
天啊,刚刚注意到OP的名字 - 这个世界真小,Harel :D - Stephan Tual
显示剩余12条评论
1个回答

0

我发现这通常是重复ID的问题。@Harel的问题没有包括实际渲染集合的代码,因此我们无法确定他问题的根本原因,但@Drew在评论中提供的重现会抛出此错误,因为它正在呈现具有重复“_id”值的对象数组。

我已经组合了一个工作版本的@Drew的重现:

https://github.com/alanning/meteor-buggy-fix

关键修复方法是确保插入的饮料项目没有重复的“_id”字段:

  Template.drink_from_menu.events({
    'click .buy_drink': function () {
      var drink = {name: this.name, price: this.price};

      console.log("this = ", this);

      // using 'this' doesn't work because it already has a '_id' field and 
      // you would be trying to render multiple drinks with the same id
      // which causes Spark to throw the "Can't create second landmark 
      // in same branch" error
      //Tabs.update({_id:Session.get('tabId')}, {$push: {ordered_drinks: this}});

      // either ensure that the objects you want Spark to render have a 
      // unique id or leave off the _id completely and let Spark do it for you
      Tabs.update({_id:Session.get('tabId')}, {$push: {ordered_drinks: drink}});
    }
  });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接