对象来自哪个Meteor集合?

时间:2014-12-17 16:34:05

标签: javascript collections meteor

我有一个自定义块帮助器(本质上是一个{{#each}}循环),它呈现Mongo.Collection.find()的结果:

{{#sortable items=someCursor}}
  {{> sortableItemTarget}}
{{/sortable}}

在sortableItemTarget模板事件处理程序中,如何访问父数据上下文,即项目来自的集合(或至少是光标)?

由于a bug,自定义块帮助程序模板事件处理程序无权访问父数据上下文。

换句话说,如果我跑

var items = Mongo.Collection('items');
...
var item = items.findOne({...});

如何使用item

之类的内容轻松删除其集合中的item._collection.remove()

最小代码为in this GitHub repo

2 个答案:

答案 0 :(得分:1)

我知道我已经发表了评论,但在考虑了30秒之后,我觉得我应该给这个答案更合适。

我在自己的Meteor航行中学到的一个技巧是,在处理帮助器和事件监听器时,指向this的上下文。例如,如果我有一个{{#with XXX}}块,那么被调用的任何事件处理程序或帮助程序都会引用XXX作为this。很好的功能,我可以用非常通用的方式编写我的代码来简单地处理任何一个给定的元素,并且它得到倍增而且只是"工作"因为流星本质上的众多。

其次,我通过异步Meteor.call进行所有数据操作。我还没有深入研究组合客户端和服务器Meteor.call,因为我还没有这个需要,但是我已经查看了代码并且它看起来并不复杂。至少。我这样做是为了保持反应性,并让Meteor这样做" thang"并在数据更新时更新模板。

最后,当没有简单的方法来获取我想要的数据时,我在Blaze.getData()找到了爱。事实证明,在我的DOM的任何部分获取数据都是不可或缺的。

所以,为了实现这一点,这是一个例子,我直接从我的头盖骨拉出来,没有测试。

首先,我需要在我的模板中使用循环。类似的东西:

<table>
  {{#each myWidgets}}
    <tr>
      <td>{{myWidgetTitle}}</td>
      <td>{{myWidgetData}}</td>
      <td><button class="bntRemoveWidget">Remove Widget</button></td>
    </tr>
  {{/each}}
</table>

这里我假设我的模板数据有一个.myWidgets数组,每个&#34;小部件&#34;有一个myWidgetTitle和一个myWidgetData属性。我还有一个按钮来删除小部件。

接下来,我需要一个事件处理程序。很简单

Template.myWidgetTable.events({
  'click .btnRemoveWidget': function(event, tmpl) {
    var myWidget = Blaze.getData(event.getTarget());  // This bit of magic gets me the widget in context where the button was clicked!
    Meteor.call('removeWidget', myWidget._id, function(err, result) {
      if (err) {
        // Do something with the error!
      } else {
        // Add some success message???
      }
    });
  }
});

最后,我需要编写处理删除的方法(我不编写内容,因为这是与问题无关的单独讨论):

Meteor.methods({
  removeWidget: function(myWidgetId) {
    // Select the item that contains the widget id, remove it, and save it back to the collection
  }
});

现在,由于我的模板对包含myWidgets数组的对象具有反应性,因此只需更新服务器上数组的内容就会导致相应的连锁反应在UI中实现。再说一遍,你可以得到#34;花哨的&#34;使用Meteor.call和Meteor.methods制作相应的客户端和服务器版本,将会发生的情况是该方法在两者上运行,更新客户端以便UI在不等待的情况下获得即时更新,而且还更新服务器以便实际数据库中的数据是正确的。当发布通道最终同步时,Meteor足够智能,可以协调对客户端所做的更改与服务器中所做的更改。它也可以缓存来自客户端的更新,并在连接恢复时同步,尽管我还没有测试过。

答案 1 :(得分:1)

我不确定这会回答你的问题,因为你的github repo似乎增加了事件访问对象数据的复杂性。但根据提供的代码,您可以使用transform选项在items.remove( item._id )的任何地方提供item

像这样:

var item = Items.findOne( {...}, {transform: function( i ){ 
  i.remove = function() {return items.remove( i._id )};
  return i;
}});

//then where ever you can access item
item.remove();

我根据排行榜示例在meteorpad中对此进行了测试,效果很好。选择一个玩家将其从玩家集合中删除。

相关问题