如何在没有Session的Meteor中从事件处理程序修改模板实例?

时间:2013-03-29 06:43:36

标签: javascript meteor

我正在尝试实现可扩展帖子评论的层次结构,例如Quora,以便用户可以点击评论并查看任何回复。

为此,我想跟踪每个“评论”模板实例是否“展开”,切换事件处理程序中的状态。

我可以使用整个堆栈会话变量(即每个注释一个)来执行此操作,但这看起来很笨,因为任何给定页面上都有任意数量的注释。

下面是我正在尝试的内容的片段。

JS:

Template.comment_item.events = {
    'click #comment-content': function( e, instance ) {
        this.expanded = true;  // also tried instance.data.expanded = true
    }
};

Template.comment_item.helpers({
    showChildComments: function(){
      this.expanded;
    }
});

HTML:

<template name="comment_item">
  <li class="comment comment-displayed" id="{{_id}}">
   <div class="comment-body">
      <div id="comment-content">
        <!-- some comment data here -->
      </div>
      {{#if showChildComments}}
      <ul class="comment-children comment-list">
          {{#each child_comments}}
            {{> comment_item}}
          {{/each}}
      </ul>
      {{/if}}
    </div>
  </li>
</template>

不幸的是,当我单步执行时,似乎在showChildComments帮助器中,模板实例无法看到扩展变量。我在文档中注意到它说instance.data只在事件图中读取。

有没有办法直接修改事件地图中的模板实例?

2 个答案:

答案 0 :(得分:10)

您可以在其创建的事件处理程序中为模板实例创建属性。您可以访问模板实例作为事件映射函数的第二个参数。

Template.comment_item.created = function() {
  this.showChildren = false;
};

Template.comment_item.events({
  'click .comment-content': function(event, template) {
    template.showChildren = true;
  }
});

但是:

  1. 您无法在模板助手中访问模板实例及其属性。
  2. 您的模板助手无论如何都需要获得“被动”数据源,以便当场更改。
  3. 即使您遇到创建自己的被动数据源的麻烦,您使用此功能的方法仍然为页面上的X条评论量创建X量的变量。这似乎是在内存中实现一个功能的大量变量。
  4. 我建议您改为将模板简化为:

    <template name="comment_item">
      <li class="comment comment-displayed" id="{{_id}}">
       <div class="comment-body">
          <div class="comment-content">  <!-- changed this to a class -->
            <!-- some comment data here -->
          </div>
        </div>
      </li>
    </template>
    

    然后以编程方式将子注释添加到事件处理程序中的comment-body。请记住Meteor文档中的以下内容:

      

    您声明为<template name="foo"> ... </template>的模板   可以作为Template.foo函数访问,它返回一个字符串   调用时的HTML。

    哦,您将上下文作为JSON对象传递给模板函数。 E.g:

    var context = {_id: comment_id, text: "Comment text!"};
    Template.comment_item(context);
    

答案 1 :(得分:6)

更新

Meteor现在使用Template.instance()为您提供访问帮助程序中的模板实例。事实上,它是提高模板可重用性的好方法。

以下示例来源于this article,由Percolate Studio的David Burles撰写。

Template.hello.created = function () {
  // counter starts at 0
  this.state = new ReactiveDict();
  this.state.set('counter', 0);
}; 

Template.hello.helpers({
  counter: function () {
    return Template.instance().state.get('counter');
  }
});

Template.hello.events({
  'click button': function (event, template) {
    // increment the counter when button is clicked
    template.state.set('counter', template.state.get('counter') + 1);
  }
});

The article很好地说明了为什么要这种方法。

在模板实例中存储信息的优点是,您可以使模板越来越模块化,并且越来越依赖于它们的使用位置。